diff --git a/desktop/flipper-common/src/server-types.tsx b/desktop/flipper-common/src/server-types.tsx index 19b9824d5..dfe37ba61 100644 --- a/desktop/flipper-common/src/server-types.tsx +++ b/desktop/flipper-common/src/server-types.tsx @@ -134,6 +134,7 @@ export type IOSDeviceParams = { export type FlipperServerCommands = { 'get-config': () => Promise; 'get-changelog': () => Promise; + 'device-list': () => Promise; 'device-start-logging': (serial: string) => Promise; 'device-stop-logging': (serial: string) => Promise; 'device-supports-screenshot': (serial: string) => Promise; @@ -153,6 +154,7 @@ export type FlipperServerCommands = { 'device-clear-logs': (serial: string) => Promise; 'device-navigate': (serial: string, location: string) => Promise; 'metro-command': (serial: string, command: string) => Promise; + 'client-list': () => Promise; 'client-request': (clientId: string, payload: any) => Promise; 'client-request-response': ( clientId: string, diff --git a/desktop/flipper-server-core/src/FlipperServerImpl.tsx b/desktop/flipper-server-core/src/FlipperServerImpl.tsx index fe295dd0b..89623349f 100644 --- a/desktop/flipper-server-core/src/FlipperServerImpl.tsx +++ b/desktop/flipper-server-core/src/FlipperServerImpl.tsx @@ -214,6 +214,9 @@ export class FlipperServerImpl implements FlipperServer { private commandHandler: FlipperServerCommands = { 'get-config': async () => this.config, 'get-changelog': getChangelog, + 'device-list': async () => { + return Array.from(this.devices.values()).map((d) => d.info); + }, 'device-start-logging': async (serial: string) => this.getDevice(serial).startLogging(), 'device-stop-logging': async (serial: string) => @@ -242,6 +245,9 @@ export class FlipperServerImpl implements FlipperServer { } device.sendCommand(command); }, + 'client-list': async () => { + return Array.from(this.server.connections.values()).map((c) => c.client); + }, 'client-request': async (clientId, payload) => { this.server.connections.get(clientId)?.connection?.send(payload); }, diff --git a/desktop/flipper-ui-core/src/dispatcher/flipperServer.tsx b/desktop/flipper-ui-core/src/dispatcher/flipperServer.tsx index 5b8427d86..9ee7269ba 100644 --- a/desktop/flipper-ui-core/src/dispatcher/flipperServer.tsx +++ b/desktop/flipper-ui-core/src/dispatcher/flipperServer.tsx @@ -14,6 +14,7 @@ import { Logger, NoLongerConnectedToClientError, isTest, + DeviceDescription, } from 'flipper-common'; import Client from '../Client'; import {notification} from 'antd'; @@ -64,37 +65,7 @@ export function connectFlipperServerToStore( }); server.on('device-connected', (deviceInfo) => { - logger.track('usage', 'register-device', { - os: deviceInfo.os, - name: deviceInfo.title, - serial: deviceInfo.serial, - }); - - const existing = store - .getState() - .connections.devices.find( - (device) => device.serial === deviceInfo.serial, - ); - // handled outside reducer, as it might emit new redux actions... - if (existing) { - if (existing.connected.get()) { - console.warn( - `Tried to replace still connected device '${existing.serial}' with a new instance.`, - ); - } - existing.destroy(); - } - - const device = new BaseDevice(server, deviceInfo); - device.loadDevicePlugins( - store.getState().plugins.devicePlugins, - store.getState().connections.enabledDevicePlugins, - ); - - store.dispatch({ - type: 'REGISTER_DEVICE', - payload: device, - }); + handleDeviceConnected(server, store, logger, deviceInfo); }); server.on('device-disconnected', (device) => { @@ -141,6 +112,26 @@ export function connectFlipperServerToStore( 'Flipper server started and accepting device / client connections', ); + server + .exec('device-list') + .then((devices) => { + // register all devices + devices.forEach((device) => { + handleDeviceConnected(server, store, logger, device); + }); + }) + .then(() => { + return server.exec('client-list'); + }) + .then((clients) => { + clients.forEach((client) => { + handleClientConnected(server, store, logger, client); + }); + }) + .catch((e) => { + console.error('Failed to get initial device/client list: ', e); + }); + return () => { sideEffectDisposer?.(); server.close(); @@ -182,6 +173,43 @@ function startSideEffects(store: Store, server: FlipperServer) { }; } +function handleDeviceConnected( + server: FlipperServer, + store: Store, + logger: Logger, + deviceInfo: DeviceDescription, +) { + logger.track('usage', 'register-device', { + os: deviceInfo.os, + name: deviceInfo.title, + serial: deviceInfo.serial, + }); + + const existing = store + .getState() + .connections.devices.find((device) => device.serial === deviceInfo.serial); + // handled outside reducer, as it might emit new redux actions... + if (existing) { + if (existing.connected.get()) { + console.warn( + `Tried to replace still connected device '${existing.serial}' with a new instance.`, + ); + } + existing.destroy(); + } + + const device = new BaseDevice(server, deviceInfo); + device.loadDevicePlugins( + store.getState().plugins.devicePlugins, + store.getState().connections.enabledDevicePlugins, + ); + + store.dispatch({ + type: 'REGISTER_DEVICE', + payload: device, + }); +} + export async function handleClientConnected( server: Pick, store: Store,