diff --git a/.gitignore b/.gitignore index f7c3f01..8b2b642 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.pyc *.db +build/ js-build/ babel-build/ log/ diff --git a/index.js b/index.js index aae5448..dcf939c 100644 --- a/index.js +++ b/index.js @@ -8,8 +8,10 @@ let win function createWindow () { // Create the browser window. - win = new BrowserWindow({width: 1280, height: 800}) - win.setMenu(null) + win = new BrowserWindow({width: 1280, height: 780}) + // setTimeout(() => { + // win.setMenu(null) + // }, 1500) // and load the index.html of the app. win.loadURL(url.format({ diff --git a/lib/modules/base/inspector-panel.jsx b/lib/modules/base/inspector-panel.jsx index cb6b096..7d42e47 100644 --- a/lib/modules/base/inspector-panel.jsx +++ b/lib/modules/base/inspector-panel.jsx @@ -134,7 +134,7 @@ class ElementPane extends MouseoverComponent { constructor(props) { super(props) this.state = Object.assign({ - refreshing: false, + refreshing: true, coordTipsCoord: [0, 0], elementDetected: null, // 只能选择模式检测出来的节点 }, this.superState()) @@ -311,6 +311,12 @@ class ElementPane extends MouseoverComponent {
{' ' + node.name}
} + componentWillReceiveProps(nextProps) { + this.setState({refreshing: false}) + } + componentDidMount(nextProps) { + this.setState({refreshing: false}) + } render() { let cursor = this.props.hierarchyCursor @@ -403,6 +409,7 @@ export class InspectorPanel extends React.Component { } autoBind(this) + this.ref_elementPane = null this.ref_elementPath = null this.ref_hierarchyPane = null this.ref_attributePane = null @@ -496,6 +503,7 @@ export class InspectorPanel extends React.Component { } } handleRefreshRequest() { + this.ref_elementPane.setState({refreshing: true, screen: ''}) this.props.onRefreshRequest(this.state.elementPaneWidth) } @@ -548,7 +556,7 @@ export class InspectorPanel extends React.Component { {!!tree && } - const elementPane = + const elementPane = this.ref_elementPane = r} parent={this} elementSelecting={this.state.elementSelecting} hierarchyCursor={cursor} hierarchyTree={this.props.hierarchyTree} screen={this.props.screen} screenWidth={this.props.screenWidth} screenHeight={this.props.screenHeight} /> const attributePane =
this.ref_attributePane = r}> {!!cursor &&
path: diff --git a/lib/modules/temp/index.jsx b/lib/modules/temp/index.jsx index 44fbb1d..15925dd 100644 --- a/lib/modules/temp/index.jsx +++ b/lib/modules/temp/index.jsx @@ -15,14 +15,32 @@ import {SPAContainer} from '../base/spa' import {InspectorPanel} from '../base/inspector-panel' +const path = window.require('path') +const ApkReader = window.require('node-apk-parser') const adb = window.require('adbkit') const adbClient = adb.createClient() const eventEmitter = new EventEmitter() const PocoServicePackage = 'com.netease.open.pocoservice' +const PocoServicePackageTest = 'com.netease.open.pocoservice.test' const PocoServiceApk = 'pocoservice-debug.apk' const PocoServiceApkTest = 'pocoservice-debug-androidTest.apk' +var checkInstalled = (sn, apkfile, packageName) => { + if (!path.isAbsolute(apkfile)) { + apkfile = path.join(window.__dirname, apkfile) + } + let manifest = ApkReader.readFile(apkfile).readManifestSync() + return adbClient.shell(sn, `dumpsys package ${packageName}`) + .then(adb.util.readAll) + .then(output => { + let versionCode = output.toString().match(/versionCode=(\d+)/) + if (versionCode) { + return parseInt(versionCode[1]) >= (manifest.versionCode || 0) + } + return false + }) +} class InspectorView extends React.Component { constructor(props) { @@ -38,33 +56,43 @@ class InspectorView extends React.Component { this.serviceStarted = false const sn = this.props.sn + let testApkShouldReinstall = false adbClient.shell(sn, `am force-stop ${PocoServicePackage}`) - adbClient.isInstalled(sn, PocoServicePackage) // 改用versionCode判断 - // 安装 + // 安装,如果主apk重装了,那么test apk也要重装 + .then(() => checkInstalled(sn, `lib/apk/${PocoServiceApk}`, PocoServicePackage)) .then(installed => { if (!installed) { + testApkShouldReinstall = true return Promise.resolve() .then(() => adbClient.push(sn, `lib/apk/${PocoServiceApk}`, `/data/local/tmp/${PocoServiceApk}`)) .then(() => adbClient.shell(sn, `pm install "/data/local/tmp/${PocoServiceApk}"`)) } }) - .then(() => { - console.log('service installed') - return Promise.resolve() - .then(() => adbClient.push(sn, `lib/apk/${PocoServiceApkTest}`, `/data/local/tmp/${PocoServiceApkTest}`)) - .then(() => adbClient.shell(sn, `pm install -r "/data/local/tmp/${PocoServiceApkTest}"`)) + .then(() => checkInstalled(sn, `lib/apk/${PocoServiceApkTest}`, PocoServicePackageTest)) + .then(installed => { + if (!installed || testApkShouldReinstall) { + return Promise.resolve() + .then(() => adbClient.push(sn, `lib/apk/${PocoServiceApkTest}`, `/data/local/tmp/${PocoServiceApkTest}`)) + .then(() => adbClient.shell(sn, `pm install -r "/data/local/tmp/${PocoServiceApkTest}"`)) + } }) + + // 启动 .then(() => { console.log('install success') - - // 启动 return new Promise(resolve => { - setTimeout(() => { - adbClient.shell(sn, `am instrument -w -e class ${PocoServicePackage}.InstrumentedTestAsLauncher#launch ${PocoServicePackage}.test/android.support.test.runner.AndroidJUnitRunner`) + let startInstrument = () => { + return Promise.resolve() + .then(() => adbClient.shell(sn, `am force-stop ${PocoServicePackage}`)) + .then(() => adbClient.shell(sn, `am instrument -w -e class ${PocoServicePackage}.InstrumentedTestAsLauncher#launch ${PocoServicePackage}.test/android.support.test.runner.AndroidJUnitRunner`)) .then(adb.util.readAll) .then(output => { console.log(output.toString()) + setTimeout(startInstrument, 1000) // instrument 启动失败的话,就重新启动 }) + } + setTimeout(() => { + startInstrument() console.log('poco service is starting') setTimeout(() => { // 还要延迟一下子这个service才启动起来 @@ -72,11 +100,10 @@ class InspectorView extends React.Component { }, 500) }, 500) }) - - }) + + // forward .then(() => { - // forward console.log('poco service forward to tcp:10080') return adbClient.forward(sn, 'tcp:10080', 'tcp:10080') }) @@ -133,7 +160,7 @@ class InspectorView extends React.Component { {toolBarButton('keyboard_backspace', '返回', this.handleBackToDeviceSelect)} - {`${this.props.device.manufacture} (${this.props.sn})`} + {`${this.props.device.model} (${this.props.sn})`} @@ -152,7 +179,7 @@ class DeviceSelection extends React.Component { constructor(props) { super(props) this.state = { - devices: {}, // id -> {id: '', type: ''} + devices: {}, // id -> {id: '', type: '', model: ''} selectedDeviceSerial: null, } autoBind(this) @@ -168,9 +195,19 @@ class DeviceSelection extends React.Component { adbClient.trackDevices() .then(tracker => { tracker.on('add', device => { - let {devices} = this.state - devices[device.id] = device - this.setState({devices}) + adbClient.getProperties(device.id) + .then(properties => { + let model = properties['ro.product.model'] + let manufacture = properties['ro.product.manufacturer'] + return model || manufacturer + }) + .then(model => { + let {devices} = this.state + let deviceinfo = devices[device.id] + deviceinfo.model = model + devices[device.id] = deviceinfo + this.setState({devices}) + }) }) tracker.on('remove', device => { let {devices} = this.state @@ -189,14 +226,28 @@ class DeviceSelection extends React.Component { this.setState({selectedDeviceSerial: null}) } componentDidMount() { - this.startDeviceTracking() + setTimeout(this.startDeviceTracking, 1000) adbClient.listDevices() .then(devs => { - let devices = {} - for (let dev of devs) { - devices[dev.id] = dev - } - this.setState({devices}) + Promise.all(_.map(devs, dev => { + return adbClient.getProperties(dev.id) + .then(properties => { + let model = properties['ro.product.model'] + let manufacture = properties['ro.product.manufacturer'] + return [dev, model || manufacturer] + }) + })) + .then(devModels => { + let devices = {} + for (let devmodel of devModels) { + let [dev, model] = devmodel + devices[dev.id] = Object.assign({model}, dev) + } + return devices + }) + .then(devices => { + this.setState({devices}) + }) }) eventEmitter.on('back-to-device-selection', this.handleBackToThisPage) @@ -208,10 +259,10 @@ class DeviceSelection extends React.Component { render() { let devlist = _.map(this.state.devices, dev => { - return + return }) return
- {this.state.selectedDeviceSerial && } + {this.state.selectedDeviceSerial && } {!this.state.selectedDeviceSerial &&

Poco Hierarchy Viewer

{Object.keys(this.state.devices).length === 0 &&
No devices present
} diff --git a/package.json b/package.json index 14d4a41..d208325 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "jquery": "^3.2.1", "lodash": "^4.17.4", "loose-envify": "^1.3.1", + "node-apk-parser": "^0.2.3", "pako": "^1.0.5", "react": "^15.6.1", "react-addons-css-transition-group": "^15.6.0", @@ -55,5 +56,8 @@ "uuid-js": "^0.7.5", "vinyl-source-stream": "^1.1.0", "watchify": "^3.9.0" + }, + "devDependencies": { + "electron-packager": "^8.7.2" } }