diff --git a/desktop/app/src/chrome/plugin-manager/__tests__/PluginInstaller.node.tsx b/desktop/app/src/chrome/plugin-manager/__tests__/PluginInstaller.node.tsx index 80c414db3..1e0a638e3 100644 --- a/desktop/app/src/chrome/plugin-manager/__tests__/PluginInstaller.node.tsx +++ b/desktop/app/src/chrome/plugin-manager/__tests__/PluginInstaller.node.tsx @@ -33,6 +33,7 @@ const samplePluginDetails1: UpdatablePluginDetails = { entry: './test/index.js', version: '0.1.0', specVersion: 2, + pluginType: 'client', main: 'dist/bundle.js', dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample1', source: 'src/index.js', @@ -52,6 +53,7 @@ const samplePluginDetails2: UpdatablePluginDetails = { entry: './test/index.js', version: '0.2.0', specVersion: 2, + pluginType: 'client', main: 'dist/bundle.js', dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample2', source: 'src/index.js', diff --git a/desktop/app/src/devices/AndroidDevice.tsx b/desktop/app/src/devices/AndroidDevice.tsx index 7b091e2b8..1666e5dc7 100644 --- a/desktop/app/src/devices/AndroidDevice.tsx +++ b/desktop/app/src/devices/AndroidDevice.tsx @@ -16,6 +16,7 @@ import type {LogLevel, DeviceType} from 'flipper-plugin'; import which from 'which'; import {spawn} from 'child_process'; import {dirname} from 'path'; +import {DeviceSpec} from 'flipper-plugin-lib'; const DEVICE_RECORDING_DIR = '/sdcard/flipper_recorder'; @@ -27,8 +28,9 @@ export default class AndroidDevice extends BaseDevice { adb: ADBClient, abiList: Array, sdkVersion: string, + specs: DeviceSpec[] = [], ) { - super(serial, deviceType, title, 'Android'); + super(serial, deviceType, title, 'Android', specs); this.adb = adb; this.icon = 'icons/android.svg'; this.abiList = abiList; diff --git a/desktop/app/src/devices/BaseDevice.tsx b/desktop/app/src/devices/BaseDevice.tsx index 072ae86a3..6ef409d17 100644 --- a/desktop/app/src/devices/BaseDevice.tsx +++ b/desktop/app/src/devices/BaseDevice.tsx @@ -17,6 +17,7 @@ import { } from 'flipper-plugin'; import type {DevicePluginDefinition, DevicePluginMap} from '../plugin'; import {getFlipperLibImplementation} from '../utils/flipperLibImplementation'; +import {DeviceSpec, OS as PluginOS} from 'flipper-plugin-lib'; export type DeviceShell = { stdout: stream.Readable; @@ -24,6 +25,8 @@ export type DeviceShell = { stdin: stream.Writable; }; +export type OS = PluginOS | 'Windows' | 'MacOS' | 'JSWebApp'; + export type DeviceExport = { os: OS; title: string; @@ -32,14 +35,19 @@ export type DeviceExport = { logs: Array; }; -export type OS = 'iOS' | 'Android' | 'Windows' | 'MacOS' | 'JSWebApp' | 'Metro'; - export default class BaseDevice { - constructor(serial: string, deviceType: DeviceType, title: string, os: OS) { + constructor( + serial: string, + deviceType: DeviceType, + title: string, + os: OS, + specs: DeviceSpec[] = [], + ) { this.serial = serial; this.title = title; this.deviceType = deviceType; this.os = os; + this.specs = specs; } // operating system of this device @@ -54,6 +62,9 @@ export default class BaseDevice { // serial number for this device serial: string; + // additional device specs used for plugin compatibility checks + specs: DeviceSpec[]; + // possible src of icon to display next to the device title icon: string | null | undefined; diff --git a/desktop/app/src/devices/KaiOSDevice.tsx b/desktop/app/src/devices/KaiOSDevice.tsx index d70e5feca..cc4c6f1b8 100644 --- a/desktop/app/src/devices/KaiOSDevice.tsx +++ b/desktop/app/src/devices/KaiOSDevice.tsx @@ -7,9 +7,22 @@ * @format */ +import {DeviceType} from 'flipper-plugin-lib'; import AndroidDevice from './AndroidDevice'; +import {Client as ADBClient} from 'adbkit'; export default class KaiOSDevice extends AndroidDevice { + constructor( + serial: string, + deviceType: DeviceType, + title: string, + adb: ADBClient, + abiList: Array, + sdkVersion: string, + ) { + super(serial, deviceType, title, adb, abiList, sdkVersion, ['KaiOS']); + } + async screenCaptureAvailable() { // The default way of capturing screenshots through adb does not seem to work // There is a way of getting a screenshot through KaiOS dev tools though diff --git a/desktop/app/src/dispatcher/__tests__/plugins.node.tsx b/desktop/app/src/dispatcher/__tests__/plugins.node.tsx index cfdd57dc3..6ce67656d 100644 --- a/desktop/app/src/dispatcher/__tests__/plugins.node.tsx +++ b/desktop/app/src/dispatcher/__tests__/plugins.node.tsx @@ -41,6 +41,7 @@ const sampleInstalledPluginDetails: InstalledPluginDetails = { name: 'other Name', version: '1.0.0', specVersion: 2, + pluginType: 'client', main: 'dist/bundle.js', source: 'src/index.js', id: 'Sample', diff --git a/desktop/app/src/plugins/TableNativePlugin.tsx b/desktop/app/src/plugins/TableNativePlugin.tsx index e531dfb2f..0dfafe733 100644 --- a/desktop/app/src/plugins/TableNativePlugin.tsx +++ b/desktop/app/src/plugins/TableNativePlugin.tsx @@ -261,6 +261,7 @@ export default function createTableNativePlugin(id: string, title: string) { title, icon: 'apps', name: id, + pluginType: 'client', // all hmm... specVersion: 1, version: 'auto', diff --git a/desktop/app/src/reducers/__tests__/plugins.node.tsx b/desktop/app/src/reducers/__tests__/plugins.node.tsx index d189a77f7..90e27708c 100644 --- a/desktop/app/src/reducers/__tests__/plugins.node.tsx +++ b/desktop/app/src/reducers/__tests__/plugins.node.tsx @@ -88,6 +88,7 @@ test('add gatekeeped plugin', () => { version: '1.0.0', dir: '/plugins/test', specVersion: 2, + pluginType: 'client', source: 'src/index.ts', isBundled: false, isActivatable: true, diff --git a/desktop/app/src/utils/testUtils.tsx b/desktop/app/src/utils/testUtils.tsx index 24058fbda..4708ac96a 100644 --- a/desktop/app/src/utils/testUtils.tsx +++ b/desktop/app/src/utils/testUtils.tsx @@ -48,6 +48,7 @@ export function createMockDownloadablePluginDetails( main: 'dist/bundle.js', source: 'src/index.tsx', specVersion: 2, + pluginType: 'client', title: title ?? id, version: version, downloadUrl: `http://localhost/${lowercasedID}/${version}`, diff --git a/desktop/flipper-plugin/src/plugin/DevicePlugin.tsx b/desktop/flipper-plugin/src/plugin/DevicePlugin.tsx index f58f9e8d9..e2a57ec21 100644 --- a/desktop/flipper-plugin/src/plugin/DevicePlugin.tsx +++ b/desktop/flipper-plugin/src/plugin/DevicePlugin.tsx @@ -10,6 +10,7 @@ import {SandyPluginDefinition} from './SandyPluginDefinition'; import {BasePluginInstance, BasePluginClient} from './PluginBase'; import {FlipperLib} from './FlipperLib'; +import {DeviceType as PluginDeviceType} from 'flipper-plugin-lib'; export type DeviceLogListener = (entry: DeviceLogEntry) => void; @@ -40,7 +41,7 @@ export interface Device { onLogEntry(cb: DeviceLogListener): () => void; } -export type DeviceType = 'emulator' | 'physical'; +export type DeviceType = PluginDeviceType; export type DevicePluginPredicate = (device: Device) => boolean; diff --git a/desktop/flipper-plugin/src/test-utils/test-utils.tsx b/desktop/flipper-plugin/src/test-utils/test-utils.tsx index bf98db906..ad80231a5 100644 --- a/desktop/flipper-plugin/src/test-utils/test-utils.tsx +++ b/desktop/flipper-plugin/src/test-utils/test-utils.tsx @@ -390,6 +390,7 @@ export function createMockPluginDetails( dir: '', name: 'TestPlugin', specVersion: 0, + pluginType: 'client', entry: '', isBundled: false, isActivatable: true, diff --git a/desktop/pkg/schemas/plugin-package-v2.json b/desktop/pkg/schemas/plugin-package-v2.json index 46bf0bc1e..7569998ca 100644 --- a/desktop/pkg/schemas/plugin-package-v2.json +++ b/desktop/pkg/schemas/plugin-package-v2.json @@ -39,6 +39,43 @@ "pattern": "flipper-plugin" }, "errorMessage": "should contain keyword \"flipper-plugin\"" + }, + "pluginType": { + "description": "Type of the plugin - client or device. If omitted, \"client\" type is used by default.", + "type": "string", + "enum": ["client", "device"] + }, + "supportedDevices": { + "description": "List of devices supported by the plugin. The list could contain multiple devices each defined as conjunction of several properties.", + "type": "array", + "items": { + "description": "Device definition. E.g. {\"os\": \"Android\", \"type\": \"physical\", \"archived\": false} means that plugin supports only Android physical unarchived devices.", + "type": "object", + "properties": { + "os": { + "description": "Device OS: iOS, Android or Metro. Lack of this property means that all OSes supported.", + "type": "string", + "enum": ["iOS", "Android", "Metro"] + }, + "type": { + "description": "Device type: physical or emulator. Lack of this property means both physical and emulator devices supported.", + "type": "string", + "enum": ["physical", "emulator"] + }, + "archived": { + "description": "Specifies support for archived devices. Lack of this property means that both live and archived devices supported. False means only live devices supported. True means only archived devices supported.", + "type": "boolean" + }, + "specs": { + "description": "Additional specs required for plugin, e.g. \"KaiOS\" runtime.", + "type": "array", + "items": { + "type": "string", + "enum": ["KaiOS"] + } + } + } + } } }, "required": [ diff --git a/desktop/plugin-lib/src/PluginDetails.ts b/desktop/plugin-lib/src/PluginDetails.ts index 50b85f056..0193ff62f 100644 --- a/desktop/plugin-lib/src/PluginDetails.ts +++ b/desktop/plugin-lib/src/PluginDetails.ts @@ -27,8 +27,25 @@ export interface PluginDetails { url?: string; }; flipperSDKVersion?: string; + pluginType: PluginType; + supportedDevices?: SupportedDevice[]; } +export interface SupportedDevice { + readonly os?: OS; + readonly type?: DeviceType; + readonly archived?: boolean; + readonly specs?: DeviceSpec[]; +} + +export type OS = 'iOS' | 'Android' | 'Metro'; + +export type DeviceType = 'emulator' | 'physical'; + +export type PluginType = 'client' | 'device'; + +export type DeviceSpec = 'KaiOS'; + export interface ConcretePluginDetails extends PluginDetails { // Determines whether the plugin is a part of the Flipper JS bundle. isBundled: boolean; diff --git a/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts b/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts index 65974fd96..0d815d97b 100644 --- a/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts +++ b/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts @@ -49,8 +49,10 @@ test('getPluginDetailsV1', async () => { "isBundled": false, "main": "dist/bundle.js", "name": "flipper-plugin-test", + "pluginType": "client", "source": "src/index.tsx", "specVersion": 1, + "supportedDevices": undefined, "title": "Test Plugin", "version": "2.0.0", } @@ -88,8 +90,10 @@ test('getPluginDetailsV2', async () => { "isBundled": false, "main": "dist/bundle.js", "name": "flipper-plugin-test", + "pluginType": "client", "source": "src/index.tsx", "specVersion": 2, + "supportedDevices": undefined, "title": "Test", "version": "3.0.1", } @@ -127,8 +131,10 @@ test('id used as title if the latter omited', async () => { "isBundled": false, "main": "dist/bundle.js", "name": "flipper-plugin-test", + "pluginType": "client", "source": "src/index.tsx", "specVersion": 2, + "supportedDevices": undefined, "title": "test", "version": "3.0.1", } @@ -165,8 +171,10 @@ test('name without "flipper-plugin-" prefix is used as title if the latter omite "isBundled": false, "main": "dist/bundle.js", "name": "flipper-plugin-test", + "pluginType": "client", "source": "src/index.tsx", "specVersion": 2, + "supportedDevices": undefined, "title": "test", "version": "3.0.1", } @@ -206,10 +214,75 @@ test('flipper-plugin-version is parsed', async () => { "isBundled": false, "main": "dist/bundle.js", "name": "flipper-plugin-test", + "pluginType": "client", "source": "src/index.tsx", "specVersion": 2, + "supportedDevices": undefined, "title": "test", "version": "3.0.1", } `); }); + +test('plugin type and supported devices parsed', async () => { + const pluginV2 = { + $schema: 'https://fbflipper.com/schemas/plugin-package/v2.json', + name: 'flipper-plugin-test', + title: 'Test', + version: '3.0.1', + pluginType: 'device', + supportedDevices: [ + {os: 'Android', archived: false}, + {os: 'Android', type: 'physical', specs: ['KaiOS']}, + {os: 'iOS', type: 'emulator'}, + ], + main: 'dist/bundle.js', + flipperBundlerEntry: 'src/index.tsx', + description: 'Description of Test Plugin', + gatekeeper: 'GK_flipper_plugin_test', + }; + jest.mock('fs-extra', () => jest.fn()); + fs.readJson = jest.fn().mockImplementation(() => pluginV2); + const details = await getInstalledPluginDetails(pluginPath); + details.dir = normalizePath(details.dir); + details.entry = normalizePath(details.entry); + expect(details).toMatchInlineSnapshot(` + Object { + "bugs": undefined, + "category": undefined, + "description": "Description of Test Plugin", + "dir": "/Users/mock/.flipper/thirdparty/flipper-plugin-test", + "entry": "/Users/mock/.flipper/thirdparty/flipper-plugin-test/dist/bundle.js", + "flipperSDKVersion": undefined, + "gatekeeper": "GK_flipper_plugin_test", + "icon": undefined, + "id": "flipper-plugin-test", + "isActivatable": true, + "isBundled": false, + "main": "dist/bundle.js", + "name": "flipper-plugin-test", + "pluginType": "device", + "source": "src/index.tsx", + "specVersion": 2, + "supportedDevices": Array [ + Object { + "archived": false, + "os": "Android", + }, + Object { + "os": "Android", + "specs": Array [ + "KaiOS", + ], + "type": "physical", + }, + Object { + "os": "iOS", + "type": "emulator", + }, + ], + "title": "Test", + "version": "3.0.1", + } + `); +}); diff --git a/desktop/plugin-lib/src/__tests__/getUpdatablePlugins.node.ts b/desktop/plugin-lib/src/__tests__/getUpdatablePlugins.node.ts index 2f31e0ca0..0ee7c793c 100644 --- a/desktop/plugin-lib/src/__tests__/getUpdatablePlugins.node.ts +++ b/desktop/plugin-lib/src/__tests__/getUpdatablePlugins.node.ts @@ -60,6 +60,7 @@ const installedPlugins: InstalledPluginDetails[] = [ entry: './test/index.js', version: '0.1.0', specVersion: 2, + pluginType: 'client', main: 'dist/bundle.js', dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample1', source: 'src/index.js', @@ -74,6 +75,7 @@ const installedPlugins: InstalledPluginDetails[] = [ entry: './test/index.js', version: '0.2.0', specVersion: 2, + pluginType: 'client', main: 'dist/bundle.js', dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample2', source: 'src/index.js', diff --git a/desktop/plugin-lib/src/getPluginDetails.ts b/desktop/plugin-lib/src/getPluginDetails.ts index 7d46821cc..7d837dafa 100644 --- a/desktop/plugin-lib/src/getPluginDetails.ts +++ b/desktop/plugin-lib/src/getPluginDetails.ts @@ -87,6 +87,8 @@ function getPluginDetailsV1(packageJson: any): PluginDetails { category: packageJson.category, bugs: packageJson.bugs, flipperSDKVersion: packageJson?.peerDependencies?.['flipper-plugin'], + pluginType: packageJson?.pluginType || 'client', + supportedDevices: packageJson?.supportedDevices, }; } @@ -107,6 +109,8 @@ function getPluginDetailsV2(packageJson: any): PluginDetails { category: packageJson.category, bugs: packageJson.bugs, flipperSDKVersion: packageJson?.peerDependencies?.['flipper-plugin'], + pluginType: packageJson?.pluginType || 'client', + supportedDevices: packageJson?.supportedDevices, }; } diff --git a/desktop/plugins/cpu/package.json b/desktop/plugins/cpu/package.json index 50f719cbb..e59634c00 100644 --- a/desktop/plugins/cpu/package.json +++ b/desktop/plugins/cpu/package.json @@ -2,6 +2,10 @@ "$schema": "https://fbflipper.com/schemas/plugin-package/v2.json", "name": "flipper-plugin-device-cpu", "id": "DeviceCPU", + "pluginType": "device", + "supportedDevices": [ + {"os": "Android", "type": "physical"} + ], "version": "0.0.0", "main": "dist/bundle.js", "flipperBundlerEntry": "index.tsx", diff --git a/desktop/plugins/crash_reporter/package.json b/desktop/plugins/crash_reporter/package.json index 0e5dc8eaf..83215ea97 100644 --- a/desktop/plugins/crash_reporter/package.json +++ b/desktop/plugins/crash_reporter/package.json @@ -2,6 +2,11 @@ "$schema": "https://fbflipper.com/schemas/plugin-package/v2.json", "name": "flipper-plugin-crash-reporter", "id": "CrashReporter", + "pluginType": "device", + "supportedDevices": [ + {"os": "Android"}, + {"os": "iOS", "type": "emulator"} + ], "version": "0.0.0", "description": "A plugin which will display a crash", "main": "dist/bundle.js", diff --git a/desktop/plugins/hermesdebuggerrn/package.json b/desktop/plugins/hermesdebuggerrn/package.json index 2f158abc7..a6fea8a40 100644 --- a/desktop/plugins/hermesdebuggerrn/package.json +++ b/desktop/plugins/hermesdebuggerrn/package.json @@ -2,6 +2,10 @@ "$schema": "https://fbflipper.com/schemas/plugin-package/v2.json", "name": "flipper-plugin-hermesdebuggerrn", "id": "Hermesdebuggerrn", + "pluginType": "device", + "supportedDevices": [ + {"os": "Metro", "archived": false} + ], "version": "0.0.0", "main": "dist/bundle.js", "flipperBundlerEntry": "index.tsx", diff --git a/desktop/plugins/kaios-allocations/package.json b/desktop/plugins/kaios-allocations/package.json index c16c5f24e..25ad80f86 100644 --- a/desktop/plugins/kaios-allocations/package.json +++ b/desktop/plugins/kaios-allocations/package.json @@ -3,6 +3,10 @@ "name": "flipper-plugin-kaios-big-allocations", "id": "kaios-big-allocations", "version": "0.0.0", + "pluginType": "device", + "supportedDevices": [ + {"os": "Android", "specs": ["KaiOS"]} + ], "main": "dist/bundle.js", "flipperBundlerEntry": "index.tsx", "license": "MIT", diff --git a/desktop/plugins/kaios-ram/package.json b/desktop/plugins/kaios-ram/package.json index a95418f78..4f1b6b593 100644 --- a/desktop/plugins/kaios-ram/package.json +++ b/desktop/plugins/kaios-ram/package.json @@ -3,6 +3,10 @@ "name": "flipper-plugin-kaios-graphs", "id": "kaios-graphs", "version": "0.0.0", + "pluginType": "device", + "supportedDevices": [ + {"os": "Android", "specs": ["KaiOS"]} + ], "main": "dist/bundle.js", "flipperBundlerEntry": "index.tsx", "license": "MIT", diff --git a/desktop/plugins/logs/package.json b/desktop/plugins/logs/package.json index a0639450d..5e2bf1c35 100644 --- a/desktop/plugins/logs/package.json +++ b/desktop/plugins/logs/package.json @@ -2,6 +2,12 @@ "$schema": "https://fbflipper.com/schemas/plugin-package/v2.json", "name": "flipper-plugin-device-logs", "id": "DeviceLogs", + "pluginType": "device", + "supportedDevices": [ + {"os": "Android"}, + {"os": "iOS", "type": "emulator"}, + {"os": "Metro"} + ], "version": "0.0.0", "main": "dist/bundle.js", "flipperBundlerEntry": "index.tsx", diff --git a/desktop/plugins/reactdevtools/package.json b/desktop/plugins/reactdevtools/package.json index bf72abb41..f9aaa08aa 100644 --- a/desktop/plugins/reactdevtools/package.json +++ b/desktop/plugins/reactdevtools/package.json @@ -3,6 +3,10 @@ "name": "flipper-plugin-react-devtools", "id": "React", "version": "0.0.0", + "pluginType": "device", + "supportedDevices": [ + {"os": "Metro", "archived": false} + ], "main": "dist/bundle.js", "flipperBundlerEntry": "index.tsx", "license": "MIT",