Add custom timeout to Device.installApp

Reviewed By: lblasa

Differential Revision: D39728545

fbshipit-source-id: be77a2e7ddac4071c9cafc88e67b793ee8c7631c
This commit is contained in:
Andrey Goncharov
2022-09-23 10:20:53 -07:00
committed by Facebook GitHub Bot
parent dd7ba2d6fc
commit 228de6c542
5 changed files with 89 additions and 11 deletions

View File

@@ -470,6 +470,9 @@ export type FlipperServerConfig = {
type?: FlipperServerType; type?: FlipperServerType;
}; };
export interface FlipperServerExecOptions {
timeout: number;
}
export interface FlipperServer { export interface FlipperServer {
connect(): Promise<void>; connect(): Promise<void>;
on<Event extends keyof FlipperServerEvents>( on<Event extends keyof FlipperServerEvents>(
@@ -480,6 +483,11 @@ export interface FlipperServer {
event: Event, event: Event,
callback: (payload: FlipperServerEvents[Event]) => void, callback: (payload: FlipperServerEvents[Event]) => void,
): void; ): void;
exec<Event extends keyof FlipperServerCommands>(
options: FlipperServerExecOptions,
event: Event,
...args: Parameters<FlipperServerCommands[Event]>
): ReturnType<FlipperServerCommands[Event]>;
exec<Event extends keyof FlipperServerCommands>( exec<Event extends keyof FlipperServerCommands>(
event: Event, event: Event,
...args: Parameters<FlipperServerCommands[Event]> ...args: Parameters<FlipperServerCommands[Event]>

View File

@@ -11,6 +11,8 @@ import EventEmitter from 'eventemitter3';
import { import {
ExecWebSocketMessage, ExecWebSocketMessage,
FlipperServer, FlipperServer,
FlipperServerCommands,
FlipperServerExecOptions,
ServerWebSocketMessage, ServerWebSocketMessage,
} from 'flipper-common'; } from 'flipper-common';
import ReconnectingWebSocket from 'reconnecting-websocket'; import ReconnectingWebSocket from 'reconnecting-websocket';
@@ -127,10 +129,30 @@ export function createFlipperServerWithSocket(
} }
}); });
const commandOrOptionsIsOptions = (
commandOrOptions: FlipperServerExecOptions | string,
): commandOrOptions is FlipperServerExecOptions =>
typeof commandOrOptions === 'object';
const flipperServer: FlipperServer = { const flipperServer: FlipperServer = {
async connect() {}, async connect() {},
close() {}, close() {},
exec(command, ...args): any { exec(commandOrOptions, ...argsAmbiguous): any {
let timeout: number;
let command: string;
let args: Parameters<
FlipperServerCommands[keyof FlipperServerCommands]
>;
if (commandOrOptionsIsOptions(commandOrOptions)) {
timeout = commandOrOptions.timeout;
command = argsAmbiguous[0] as string;
args = argsAmbiguous.slice(1) as typeof args;
} else {
timeout = EXEC_TIMEOUT;
command = commandOrOptions;
args = argsAmbiguous as typeof args;
}
if (connected) { if (connected) {
const id = ++requestId; const id = ++requestId;
return new Promise<any>((resolve, reject) => { return new Promise<any>((resolve, reject) => {
@@ -144,7 +166,7 @@ export function createFlipperServerWithSocket(
reject( reject(
new Error(`flipper-server: timeout for command '${command}'`), new Error(`flipper-server: timeout for command '${command}'`),
); );
}, EXEC_TIMEOUT), }, timeout),
}); });
const execMessage = { const execMessage = {

View File

@@ -239,12 +239,19 @@ export default class BaseDevice implements Device {
return this.flipperServer.exec('device-navigate', this.serial, location); return this.flipperServer.exec('device-navigate', this.serial, location);
} }
async installApp(appBundlePath: string): Promise<void> { async installApp(appBundlePath: string, timeout?: number): Promise<void> {
return this.flipperServer.exec( return timeout
'device-install-app', ? this.flipperServer.exec(
this.serial, {timeout},
appBundlePath, 'device-install-app',
); this.serial,
appBundlePath,
)
: this.flipperServer.exec(
'device-install-app',
this.serial,
appBundlePath,
);
} }
async screenshot(): Promise<Uint8Array | undefined> { async screenshot(): Promise<Uint8Array | undefined> {

View File

@@ -44,7 +44,7 @@ export interface Device {
sendMetroCommand(command: string): Promise<void>; sendMetroCommand(command: string): Promise<void>;
navigateToLocation(location: string): Promise<void>; navigateToLocation(location: string): Promise<void>;
screenshot(): Promise<Uint8Array | undefined>; screenshot(): Promise<Uint8Array | undefined>;
installApp(appBundlePath: string): Promise<void>; installApp(appBundlePath: string, timeout?: number): Promise<void>;
} }
export type DevicePluginPredicate = (device: Device) => boolean; export type DevicePluginPredicate = (device: Device) => boolean;

View File

@@ -24,6 +24,7 @@ import {
UninitializedClient, UninitializedClient,
FlipperServerConfig, FlipperServerConfig,
Logger, Logger,
FlipperServerExecOptions,
} from 'flipper-common'; } from 'flipper-common';
import {ServerDevice} from './devices/ServerDevice'; import {ServerDevice} from './devices/ServerDevice';
import {Base64} from 'js-base64'; import {Base64} from 'js-base64';
@@ -268,14 +269,54 @@ export class FlipperServerImpl implements FlipperServer {
this.events.emit('*', event, payload); this.events.emit('*', event, payload);
} }
private isExecWithOptions<Event extends keyof FlipperServerCommands>(
argsAmbiguous:
| [
FlipperServerExecOptions,
Event,
...Parameters<FlipperServerCommands[Event]>,
]
| [Event, ...Parameters<FlipperServerCommands[Event]>],
): argsAmbiguous is [
FlipperServerExecOptions,
Event,
...Parameters<FlipperServerCommands[Event]>,
] {
return typeof argsAmbiguous[0] === 'object';
}
exec<Event extends keyof FlipperServerCommands>(
options: FlipperServerExecOptions,
event: Event,
...args: Parameters<FlipperServerCommands[Event]>
): ReturnType<FlipperServerCommands[Event]>;
exec<Event extends keyof FlipperServerCommands>( exec<Event extends keyof FlipperServerCommands>(
event: Event, event: Event,
...args: Parameters<FlipperServerCommands[Event]> ...args: Parameters<FlipperServerCommands[Event]>
): ReturnType<FlipperServerCommands[Event]>; ): ReturnType<FlipperServerCommands[Event]>;
async exec<Event extends keyof FlipperServerCommands>( async exec<Event extends keyof FlipperServerCommands>(
event: Event, ...argsAmbiguous:
...args: any[] | [
FlipperServerExecOptions,
Event,
...Parameters<FlipperServerCommands[Event]>,
]
| [Event, ...Parameters<FlipperServerCommands[Event]>]
): Promise<any> { ): Promise<any> {
let _timeout: number;
let event: Event;
let args: Parameters<FlipperServerCommands[Event]>;
if (this.isExecWithOptions(argsAmbiguous)) {
_timeout = argsAmbiguous[0].timeout;
event = argsAmbiguous[1];
args = argsAmbiguous.slice(2) as typeof args;
} else {
// _timeout is currently not used, so we are setting it to a random value. Update it to a meaningful timeout before using it!
_timeout = 42;
event = argsAmbiguous[0];
args = argsAmbiguous.slice(1) as typeof args;
}
try { try {
const handler: (...args: any[]) => Promise<any> = const handler: (...args: any[]) => Promise<any> =
this.commandHandler[event]; this.commandHandler[event];