Files
flipper/desktop/flipper-plugin/src/plugin/DevicePlugin.tsx
Andrey Goncharov b80755721c Draft communication with server add-ons from the client side
Reviewed By: nikoant

Differential Revision: D34075379

fbshipit-source-id: 09f575f5cced866ad7b9290d7739ce60f38edeee
2022-02-28 03:50:34 -08:00

119 lines
3.3 KiB
TypeScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {SandyPluginDefinition} from './SandyPluginDefinition';
import {
BasePluginInstance,
BasePluginClient,
EventsContract,
MethodsContract,
} from './PluginBase';
import {FlipperLib} from './FlipperLib';
import {Atom, ReadOnlyAtom} from '../state/atom';
import {
DeviceOS,
DeviceType,
DeviceLogEntry,
CrashLog,
ServerAddOnControls,
} from 'flipper-common';
export type DeviceLogListener = (entry: DeviceLogEntry) => void;
export type CrashLogListener = (crash: CrashLog) => void;
export interface Device {
readonly isArchived: boolean;
readonly isConnected: boolean;
readonly os: DeviceOS;
readonly serial: string;
readonly deviceType: DeviceType;
readonly connected: Atom<boolean>;
executeShell(command: string): Promise<string>;
addLogListener(callback: DeviceLogListener): Symbol;
addCrashListener(callback: CrashLogListener): Symbol;
removeLogListener(id: Symbol): void;
removeCrashListener(id: Symbol): void;
executeShell(command: string): Promise<string>;
forwardPort(local: string, remote: string): Promise<boolean>;
clearLogs(): Promise<void>;
sendMetroCommand(command: string): Promise<void>;
navigateToLocation(location: string): Promise<void>;
screenshot(): Promise<Uint8Array>;
}
export type DevicePluginPredicate = (device: Device) => boolean;
export type DevicePluginFactory = (client: DevicePluginClient) => object;
export interface DevicePluginClient<
ServerAddOnEvents extends EventsContract = {},
ServerAddOnMethods extends MethodsContract = {},
> extends BasePluginClient<ServerAddOnEvents, ServerAddOnMethods> {
/**
* opens a different plugin by id, optionally providing a deeplink to bring the plugin to a certain state
*/
selectPlugin(pluginId: string, deeplinkPayload?: unknown): void;
readonly isConnected: boolean;
readonly connected: ReadOnlyAtom<boolean>;
}
export class SandyDevicePluginInstance extends BasePluginInstance {
static is(thing: any): thing is SandyDevicePluginInstance {
return thing instanceof SandyDevicePluginInstance;
}
/** client that is bound to this instance */
readonly client: DevicePluginClient;
constructor(
serverAddOnControls: ServerAddOnControls,
flipperLib: FlipperLib,
definition: SandyPluginDefinition,
device: Device,
pluginKey: string,
initialStates?: Record<string, any>,
) {
super(
serverAddOnControls,
flipperLib,
definition,
device,
pluginKey,
initialStates,
);
this.client = {
...this.createBasePluginClient(),
selectPlugin(pluginId: string, deeplink?: unknown) {
flipperLib.selectPlugin(device, null, pluginId, deeplink);
},
get isConnected() {
return device.connected.get();
},
connected: device.connected,
};
this.initializePlugin(() =>
definition.asDevicePluginModule().devicePlugin(this.client),
);
this.startServerAddOn();
}
toJSON() {
return '[SandyDevicePluginInstance]';
}
destroy() {
this.stopServerAddOn();
super.destroy();
}
protected get serverAddOnOwner() {
return this.device.serial;
}
}