Device plugin management (2/n): enable/disable, install/uninstall
Summary: *Stack summary*: this stack adds ability to manage device plugins in the same way as client plugins: install, update, uninstall, enable (star) and disable (unstar) them. *Diff summary*: implemented all plugin management actions for device plugins. Changelog: it is now possible to enable/disable and install/uninstall device plugins Reviewed By: mweststrate Differential Revision: D26337377 fbshipit-source-id: 7d1ed61a8dc5f3339e5e548c613b67bca0c27f4f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
899fcd0783
commit
4541cdc23b
@@ -21,6 +21,8 @@ import * as TestPlugin from '../../test-utils/TestPlugin';
|
||||
import {_SandyPluginDefinition as SandyPluginDefinition} from 'flipper-plugin';
|
||||
import MockFlipper from '../../test-utils/MockFlipper';
|
||||
import Client from '../../Client';
|
||||
import React from 'react';
|
||||
import BaseDevice from '../../devices/BaseDevice';
|
||||
|
||||
const pluginDetails1 = TestUtils.createMockPluginDetails({
|
||||
id: 'plugin1',
|
||||
@@ -45,10 +47,27 @@ const pluginDetails2 = TestUtils.createMockPluginDetails({
|
||||
});
|
||||
const pluginDefinition2 = new SandyPluginDefinition(pluginDetails2, TestPlugin);
|
||||
|
||||
const devicePluginDetails = TestUtils.createMockPluginDetails({
|
||||
id: 'device',
|
||||
name: 'flipper-device',
|
||||
});
|
||||
const devicePluginDefinition = new SandyPluginDefinition(devicePluginDetails, {
|
||||
supportsDevice() {
|
||||
return true;
|
||||
},
|
||||
devicePlugin() {
|
||||
return {};
|
||||
},
|
||||
Component() {
|
||||
return <h1>Plugin3</h1>;
|
||||
},
|
||||
});
|
||||
|
||||
const mockedRequirePlugin = mocked(requirePlugin);
|
||||
|
||||
let mockFlipper: MockFlipper;
|
||||
let mockClient: Client;
|
||||
let mockDevice: BaseDevice;
|
||||
|
||||
beforeEach(async () => {
|
||||
mockedRequirePlugin.mockImplementation(
|
||||
@@ -59,6 +78,8 @@ beforeEach(async () => {
|
||||
? pluginDefinition2
|
||||
: details === pluginDetails1V2
|
||||
? pluginDefinition1V2
|
||||
: details === devicePluginDetails
|
||||
? devicePluginDefinition
|
||||
: undefined)!,
|
||||
);
|
||||
mockFlipper = new MockFlipper();
|
||||
@@ -66,6 +87,7 @@ beforeEach(async () => {
|
||||
clientOptions: {supportedPlugins: ['plugin1', 'plugin2']},
|
||||
});
|
||||
mockClient = initResult.client;
|
||||
mockDevice = initResult.device;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -199,3 +221,46 @@ test('unstar plugin', async () => {
|
||||
).not.toContain('plugin1');
|
||||
expect(mockClient.sandyPluginStates.has('plugin1')).toBeFalsy();
|
||||
});
|
||||
|
||||
test('star device plugin', async () => {
|
||||
mockFlipper.dispatch(
|
||||
loadPlugin({
|
||||
plugin: devicePluginDetails,
|
||||
enable: false,
|
||||
notifyIfFailed: false,
|
||||
}),
|
||||
);
|
||||
mockFlipper.dispatch(
|
||||
starPlugin({
|
||||
plugin: devicePluginDefinition,
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
mockFlipper.getState().connections.userStarredDevicePlugins.has('device'),
|
||||
).toBeTruthy();
|
||||
expect(mockDevice.sandyPluginStates.has('device')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('unstar device plugin', async () => {
|
||||
mockFlipper.dispatch(
|
||||
loadPlugin({
|
||||
plugin: devicePluginDetails,
|
||||
enable: false,
|
||||
notifyIfFailed: false,
|
||||
}),
|
||||
);
|
||||
mockFlipper.dispatch(
|
||||
starPlugin({
|
||||
plugin: devicePluginDefinition,
|
||||
}),
|
||||
);
|
||||
mockFlipper.dispatch(
|
||||
starPlugin({
|
||||
plugin: devicePluginDefinition,
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
mockFlipper.getState().connections.userStarredDevicePlugins.has('device'),
|
||||
).toBeFalsy();
|
||||
expect(mockDevice.sandyPluginStates.has('device')).toBeFalsy();
|
||||
});
|
||||
|
||||
@@ -12,11 +12,11 @@ import {clearPluginState} from '../reducers/pluginStates';
|
||||
import type {Logger} from '../fb-interfaces/Logger';
|
||||
import {
|
||||
LoadPluginActionPayload,
|
||||
PluginCommand,
|
||||
UninstallPluginActionPayload,
|
||||
UpdatePluginActionPayload,
|
||||
pluginCommandsProcessed,
|
||||
StarPluginActionPayload,
|
||||
PluginCommand,
|
||||
} from '../reducers/pluginManager';
|
||||
import {
|
||||
getInstalledPlugins,
|
||||
@@ -28,8 +28,8 @@ import {sideEffect} from '../utils/sideEffect';
|
||||
import {requirePlugin} from './plugins';
|
||||
import {showErrorNotification} from '../utils/notifications';
|
||||
import {
|
||||
ClientPluginDefinition,
|
||||
DevicePluginDefinition,
|
||||
FlipperDevicePlugin,
|
||||
FlipperPlugin,
|
||||
PluginDefinition,
|
||||
} from '../plugin';
|
||||
@@ -41,11 +41,17 @@ import {
|
||||
registerInstalledPlugins,
|
||||
} from '../reducers/plugins';
|
||||
import {_SandyPluginDefinition} from 'flipper-plugin';
|
||||
import {pluginStarred, pluginUnstarred} from '../reducers/connections';
|
||||
import {
|
||||
devicePluginStarred,
|
||||
devicePluginUnstarred,
|
||||
pluginStarred,
|
||||
pluginUnstarred,
|
||||
} from '../reducers/connections';
|
||||
import {deconstructClientId} from '../utils/clientUtils';
|
||||
import {clearMessageQueue} from '../reducers/pluginMessageQueue';
|
||||
import {
|
||||
getPluginKey,
|
||||
isDevicePluginDefinition,
|
||||
defaultEnabledBackgroundPlugins,
|
||||
} from '../utils/pluginUtils';
|
||||
|
||||
@@ -161,7 +167,7 @@ function uninstallPlugin(store: Store, {plugin}: UninstallPluginActionPayload) {
|
||||
function updatePlugin(store: Store, payload: UpdatePluginActionPayload) {
|
||||
const {plugin, enablePlugin} = payload;
|
||||
if (isDevicePluginDefinition(plugin)) {
|
||||
return updateDevicePlugin(store, plugin);
|
||||
return updateDevicePlugin(store, plugin, enablePlugin);
|
||||
} else {
|
||||
return updateClientPlugin(store, plugin, enablePlugin);
|
||||
}
|
||||
@@ -175,8 +181,26 @@ function getSelectedAppId(store: Store) {
|
||||
return selectedApp;
|
||||
}
|
||||
|
||||
function starPlugin(store: Store, payload: StarPluginActionPayload) {
|
||||
const {plugin, selectedApp} = payload;
|
||||
function starPlugin(
|
||||
store: Store,
|
||||
{plugin, selectedApp}: StarPluginActionPayload,
|
||||
) {
|
||||
if (isDevicePluginDefinition(plugin)) {
|
||||
starDevicePlugin(store, plugin);
|
||||
} else {
|
||||
starClientPlugin(store, plugin, selectedApp);
|
||||
}
|
||||
}
|
||||
|
||||
function starClientPlugin(
|
||||
store: Store,
|
||||
plugin: ClientPluginDefinition,
|
||||
selectedApp: string | undefined,
|
||||
) {
|
||||
selectedApp = selectedApp ?? getSelectedAppId(store);
|
||||
if (!selectedApp) {
|
||||
return;
|
||||
}
|
||||
const {connections} = store.getState();
|
||||
const clients = connections.clients.filter(
|
||||
(client) => client.query.app === selectedApp,
|
||||
@@ -200,6 +224,24 @@ function starPlugin(store: Store, payload: StarPluginActionPayload) {
|
||||
}
|
||||
}
|
||||
|
||||
function starDevicePlugin(store: Store, plugin: DevicePluginDefinition) {
|
||||
const {connections} = store.getState();
|
||||
const devicesWithPlugin = connections.devices.filter((d) =>
|
||||
d.supportsPlugin(plugin.details),
|
||||
);
|
||||
if (connections.userStarredDevicePlugins.has(plugin.id)) {
|
||||
devicesWithPlugin.forEach((d) => {
|
||||
d.unloadDevicePlugin(plugin.id);
|
||||
});
|
||||
store.dispatch(devicePluginUnstarred(plugin));
|
||||
} else {
|
||||
devicesWithPlugin.forEach((d) => {
|
||||
d.loadDevicePlugin(plugin);
|
||||
});
|
||||
store.dispatch(devicePluginStarred(plugin));
|
||||
}
|
||||
}
|
||||
|
||||
function updateClientPlugin(
|
||||
store: Store,
|
||||
plugin: typeof FlipperPlugin,
|
||||
@@ -235,9 +277,16 @@ function updateClientPlugin(
|
||||
}
|
||||
}
|
||||
|
||||
function updateDevicePlugin(store: Store, plugin: DevicePluginDefinition) {
|
||||
const devices = store.getState().connections.devices;
|
||||
const devicesWithEnabledPlugin = devices.filter((d) =>
|
||||
function updateDevicePlugin(
|
||||
store: Store,
|
||||
plugin: DevicePluginDefinition,
|
||||
enable: boolean,
|
||||
) {
|
||||
if (enable) {
|
||||
store.dispatch(devicePluginStarred(plugin));
|
||||
}
|
||||
const connections = store.getState().connections;
|
||||
const devicesWithEnabledPlugin = connections.devices.filter((d) =>
|
||||
d.supportsPlugin(plugin),
|
||||
);
|
||||
devicesWithEnabledPlugin.forEach((d) => {
|
||||
@@ -295,12 +344,3 @@ function unloadPluginModule(plugin: ActivatablePluginDetails) {
|
||||
}
|
||||
unloadModule(plugin.entry);
|
||||
}
|
||||
|
||||
export function isDevicePluginDefinition(
|
||||
definition: PluginDefinition,
|
||||
): definition is DevicePluginDefinition {
|
||||
return (
|
||||
(definition as any).prototype instanceof FlipperDevicePlugin ||
|
||||
(definition instanceof _SandyPluginDefinition && definition.isDevicePlugin)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user