Move adb client creation into it's own file

Summary: Allows the created client to be reused.

Reviewed By: passy

Differential Revision: D14241449

fbshipit-source-id: 6bbb64eeb708dce9c24e4581e8480d19af998e47
This commit is contained in:
John Knox
2019-02-27 05:39:04 -08:00
committed by Facebook Github Bot
parent edbe2555fc
commit 99bb43fe32
2 changed files with 74 additions and 57 deletions

View File

@@ -7,15 +7,11 @@
import AndroidDevice from '../devices/AndroidDevice'; import AndroidDevice from '../devices/AndroidDevice';
import child_process from 'child_process'; import child_process from 'child_process';
import promiseRetry from 'promise-retry';
import {promisify} from 'util';
import type {Store} from '../reducers/index.js'; import type {Store} from '../reducers/index.js';
import type BaseDevice from '../devices/BaseDevice'; import type BaseDevice from '../devices/BaseDevice';
import type {Logger} from '../fb-interfaces/Logger.js'; import type {Logger} from '../fb-interfaces/Logger.js';
import {registerDeviceCallbackOnPlugins} from '../utils/onRegisterDevice.js'; import {registerDeviceCallbackOnPlugins} from '../utils/onRegisterDevice.js';
import {reportPlatformFailures} from '../utils/metrics'; import {getAdbClient} from '../utils/adbClient';
import adbConfig from '../utils/adbConfig';
const adb = require('adbkit-fb');
function createDevice( function createDevice(
adbClient: any, adbClient: any,
@@ -64,57 +60,6 @@ function getRunningEmulatorName(id: string): Promise<?string> {
} }
export default (store: Store, logger: Logger) => { export default (store: Store, logger: Logger) => {
/* Adbkit will attempt to start the adb server if it's not already running,
however, it sometimes fails with ENOENT errors. So instead, we start it
manually before requesting a client. */
function createClient() {
const adbPath = process.env.ANDROID_HOME
? `${process.env.ANDROID_HOME}/platform-tools/adb`
: 'adb';
return reportPlatformFailures(
promisify(child_process.exec)(`${adbPath} start-server`)
.then(result => {
if (result.error) {
throw new Error(
`Failed to start adb server: ${result.stderr.toString()}`,
);
}
})
.then(() => adb.createClient(adbConfig())),
'createADBClient.shell',
).catch(err => {
console.error(
'Failed to create adb client using shell adb command. Trying with adbkit',
);
/* In the event that starting adb with the above method fails, fallback
to using adbkit, though its known to be unreliable. */
const unsafeClient = adb.createClient(adbConfig());
return reportPlatformFailures(
promiseRetry(
(retry, number) => {
return unsafeClient
.listDevices()
.then(() => {
return unsafeClient;
})
.catch(e => {
console.warn(
`Failed to start adb client. Retrying. ${e.message}`,
);
retry(e);
});
},
{
minTimeout: 200,
retries: 5,
},
),
'createADBClient.adbkit',
);
});
}
const watchAndroidDevices = () => { const watchAndroidDevices = () => {
// get emulators // get emulators
child_process.exec( child_process.exec(
@@ -132,7 +77,7 @@ export default (store: Store, logger: Logger) => {
}, },
); );
reportPlatformFailures(createClient(), 'createADBClient') getAdbClient()
.then(client => { .then(client => {
client client
.trackDevices() .trackDevices()

72
src/utils/adbClient.js Normal file
View File

@@ -0,0 +1,72 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import {reportPlatformFailures} from './metrics';
import {promisify} from 'util';
import child_process from 'child_process';
import promiseRetry from 'promise-retry';
import adbConfig from '../utils/adbConfig';
import adbkit from 'adbkit-fb';
let instance;
export function getAdbClient(): Promise<any> {
if (!instance) {
instance = reportPlatformFailures(createClient(), 'createADBClient');
}
return instance;
}
/* Adbkit will attempt to start the adb server if it's not already running,
however, it sometimes fails with ENOENT errors. So instead, we start it
manually before requesting a client. */
function createClient() {
const adbPath = process.env.ANDROID_HOME
? `${process.env.ANDROID_HOME}/platform-tools/adb`
: 'adb';
return reportPlatformFailures(
promisify(child_process.exec)(`${adbPath} start-server`)
.then(result => {
if (result.error) {
throw new Error(
`Failed to start adb server: ${result.stderr.toString()}`,
);
}
})
.then(() => adbkit.createClient(adbConfig())),
'createADBClient.shell',
).catch(err => {
console.error(
'Failed to create adb client using shell adb command. Trying with adbkit',
);
/* In the event that starting adb with the above method fails, fallback
to using adbkit, though its known to be unreliable. */
const unsafeClient = adbkit.createClient(adbConfig());
return reportPlatformFailures(
promiseRetry(
(retry, number) => {
return unsafeClient
.listDevices()
.then(() => {
return unsafeClient;
})
.catch(e => {
console.warn(
`Failed to start adb client. Retrying. ${e.message}`,
);
retry(e);
});
},
{
minTimeout: 200,
retries: 5,
},
),
'createADBClient.adbkit',
);
});
}