From c94c2c8455f3904982a8d9e5a90fb9d3513c4bea Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Wed, 29 May 2019 09:42:32 -0700 Subject: [PATCH] Add list-devices option to list the available devices. Summary: This diff adds an option of `--list-devices` which will list the currently active devices on the machine. It will be later used to select a device by passing an `id` as an argument. Reviewed By: danielbuechele Differential Revision: D15524250 fbshipit-source-id: 7a79ceb1e431a25adcb4e05bc0cb68407c527806 --- headless/index.js | 18 ++++++++++++++++-- src/dispatcher/androidDevice.js | 22 ++++++++++++++++++---- src/dispatcher/iOSDevice.js | 14 ++++++++++++++ src/reducers/application.js | 9 +++++---- src/utils/listDevices.js | 15 +++++++++++++++ 5 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 src/utils/listDevices.js diff --git a/headless/index.js b/headless/index.js index ea35e8028..49d430df7 100644 --- a/headless/index.js +++ b/headless/index.js @@ -17,7 +17,7 @@ import { exportMetricsWithoutTrace, exportMetricsFromTrace, } from '../src/utils/exportMetrics.js'; - +import {listDevices} from '../src/utils/listDevices'; // $FlowFixMe this file exist, trust me, flow! import setup from '../static/setup.js'; @@ -60,6 +60,12 @@ yargs describe: 'Will export metrics instead of data when flipper terminates', type: 'string', }); + yargs.option('list-devices', { + alias: 'showDevices', + default: false, + describe: 'Will print the list of devices in the terminal', + type: 'boolean', + }); }, startFlipper, ) @@ -77,6 +83,7 @@ async function startFlipper({ dev, verbose, metrics, + showDevices, exit, 'insecure-port': insecurePort, 'secure-port': securePort, @@ -145,8 +152,15 @@ async function startFlipper({ devToolsEnhancer.composeWithDevTools(applyMiddleware(headlessMiddleware)), ); const logger = initLogger(store, {isHeadless: true}); - dispatcher(store, logger); + //TODO: T45068486 Refactor this function into separate components. + if (showDevices) { + const devices = await listDevices(); + originalConsole.log(devices); + process.exit(); + } + + dispatcher(store, logger); if (shouldExportMetric(metrics) && metrics && metrics.length > 0) { try { const payload = await exportMetricsFromTrace(metrics, store.getState()); diff --git a/src/dispatcher/androidDevice.js b/src/dispatcher/androidDevice.js index 8d717272f..1604c79af 100644 --- a/src/dispatcher/androidDevice.js +++ b/src/dispatcher/androidDevice.js @@ -14,11 +14,12 @@ import {registerDeviceCallbackOnPlugins} from '../utils/onRegisterDevice.js'; import {getAdbClient} from '../utils/adbClient'; import {default as which} from 'which'; import {promisify} from 'util'; +import type {ServerPorts} from '../reducers/application'; function createDevice( adbClient: any, device: any, - store: Store, + ports: ?ServerPorts, ): Promise { return new Promise((resolve, reject) => { const type = @@ -32,13 +33,22 @@ function createDevice( name = (await getRunningEmulatorName(device.id)) || name; } const androidDevice = new AndroidDevice(device.id, type, name, adbClient); - const ports = store.getState().application.serverPorts; - androidDevice.reverse([ports.secure, ports.insecure]); + if (ports) { + androidDevice.reverse([ports.secure, ports.insecure]); + } resolve(androidDevice); }); }); } +export async function getActiveAndroidDevices(): Promise> { + const client = await getAdbClient(); + const androidDevices = await client.listDevices(); + return await Promise.all( + androidDevices.map(device => createDevice(client, device)), + ); +} + function getRunningEmulatorName(id: string): Promise { return new Promise((resolve, reject) => { const port = id.replace('emulator-', ''); @@ -138,7 +148,11 @@ export default (store: Store, logger: Logger) => { }; async function registerDevice(adbClient: any, deviceData: any, store: Store) { - const androidDevice = await createDevice(adbClient, deviceData, store); + const androidDevice = await createDevice( + adbClient, + deviceData, + store.getState().application.serverPorts, + ); logger.track('usage', 'register-device', { os: 'Android', name: androidDevice.title, diff --git a/src/dispatcher/iOSDevice.js b/src/dispatcher/iOSDevice.js index 936c7ab4e..0ea0cceec 100644 --- a/src/dispatcher/iOSDevice.js +++ b/src/dispatcher/iOSDevice.js @@ -142,6 +142,20 @@ function getActiveDevices(): Promise> { }); } +export async function getActiveDevicesAndSimulators(): Promise< + Array, +> { + const activeDevices: Array> = await Promise.all([ + getActiveSimulators(), + getActiveDevices(), + ]); + const allDevices = activeDevices[0].concat(activeDevices[1]); + return allDevices.map(device => { + const {udid, type, name} = device; + return new IOSDevice(udid, type, name); + }); +} + export default (store: Store, logger: Logger) => { // monitoring iOS devices only available on MacOS. if (process.platform !== 'darwin') { diff --git a/src/reducers/application.js b/src/reducers/application.js index f1de2e237..3468dd653 100644 --- a/src/reducers/application.js +++ b/src/reducers/application.js @@ -30,6 +30,10 @@ export type LauncherMsg = { message: string, severity: 'warning' | 'error', }; +export type ServerPorts = { + insecure: number, + secure: number, +}; export type State = { leftSidebarVisible: boolean, @@ -39,10 +43,7 @@ export type State = { activeSheet: ActiveSheet, exportFile: ?string, sessionId: ?string, - serverPorts: { - insecure: number, - secure: number, - }, + serverPorts: ServerPorts, downloadingImportData: boolean, launcherMsg: LauncherMsg, }; diff --git a/src/utils/listDevices.js b/src/utils/listDevices.js new file mode 100644 index 000000000..0f3733138 --- /dev/null +++ b/src/utils/listDevices.js @@ -0,0 +1,15 @@ +/** + * 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 {getActiveAndroidDevices} from '../dispatcher/androidDevice'; +import {getActiveDevicesAndSimulators} from '../dispatcher/iOSDevice'; +import type BaseDevice from '../devices/BaseDevice'; + +export async function listDevices(): Promise> { + const androidDevices = await getActiveAndroidDevices(); + const iOSDevices = await getActiveDevicesAndSimulators(); + return iOSDevices.concat(androidDevices); +}