Make sure device plugins show up even when loaded after creating devices

Summary: The device.devicePlugins collection was not updated if new plugins were registered after creating a device. This diff fixes that.

Reviewed By: jknoxville

Differential Revision: D19536777

fbshipit-source-id: 11ed3c3383ae692ce74fd7a21704332fb319b9c4
This commit is contained in:
Michel Weststrate
2020-01-23 08:36:15 -08:00
committed by Facebook Github Bot
parent 032b594221
commit dc60d33b3a
3 changed files with 56 additions and 8 deletions

View File

@@ -10,6 +10,8 @@
import reducer from '../connections'; import reducer from '../connections';
import {State} from '../connections'; import {State} from '../connections';
import BaseDevice from '../../devices/BaseDevice'; import BaseDevice from '../../devices/BaseDevice';
import MacDevice from '../../devices/MacDevice';
import {FlipperDevicePlugin} from '../../plugin';
test('REGISTER_DEVICE doesnt remove error', () => { test('REGISTER_DEVICE doesnt remove error', () => {
const initialState: State = reducer(undefined, { const initialState: State = reducer(undefined, {
@@ -32,6 +34,27 @@ test('REGISTER_DEVICE doesnt remove error', () => {
]); ]);
}); });
test('triggering REGISTER_DEVICE before REGISTER_PLUGINS still registers device plugins', () => {
class TestDevicePlugin extends FlipperDevicePlugin<any, any, any> {
static id = 'test';
static supportsDevice() {
return true;
}
}
const stateWithDevice = reducer(undefined, {
type: 'REGISTER_DEVICE',
payload: new MacDevice(),
});
const endState = reducer(stateWithDevice, {
type: 'REGISTER_PLUGINS',
payload: [TestDevicePlugin],
});
expect(endState.devices[0].devicePlugins).toEqual(['test']);
});
test('errors are collected on a by name basis', () => { test('errors are collected on a by name basis', () => {
const initialState: State = reducer(undefined, { const initialState: State = reducer(undefined, {
type: 'SERVER_ERROR', type: 'SERVER_ERROR',

View File

@@ -27,6 +27,8 @@ import SupportRequestFormV2 from '../fb-stubs/SupportRequestFormV2';
import SupportRequestDetails from '../fb-stubs/SupportRequestDetails'; import SupportRequestDetails from '../fb-stubs/SupportRequestDetails';
import {getPluginKey} from '../utils/pluginUtils'; import {getPluginKey} from '../utils/pluginUtils';
import {deconstructClientId} from '../utils/clientUtils'; import {deconstructClientId} from '../utils/clientUtils';
import {FlipperDevicePlugin} from '../plugin';
import {RegisterPluginAction} from './plugins';
export type StaticView = export type StaticView =
| null | null
@@ -141,7 +143,8 @@ export type Action =
| { | {
type: 'SELECT_CLIENT'; type: 'SELECT_CLIENT';
payload: string; payload: string;
}; }
| RegisterPluginAction;
const DEFAULT_PLUGIN = 'DeviceLogs'; const DEFAULT_PLUGIN = 'DeviceLogs';
const DEFAULT_DEVICE_BLACKLIST = [MacDevice]; const DEFAULT_DEVICE_BLACKLIST = [MacDevice];
@@ -367,6 +370,26 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
}; };
} }
case 'REGISTER_PLUGINS': {
// plugins are registered after creating the base devices, so update them
const plugins = action.payload;
plugins.forEach(plugin => {
if (plugin.prototype instanceof FlipperDevicePlugin) {
// smell: devices are mutable
state.devices.forEach(device => {
// @ts-ignore
if (plugin.supportsDevice(device)) {
device.devicePlugins = [
...(device.devicePlugins || []),
plugin.id,
];
}
});
}
});
return state;
}
default: default:
return state; return state;
} }

View File

@@ -21,13 +21,15 @@ export type State = {
selectedPlugins: Array<string>; selectedPlugins: Array<string>;
}; };
type P = typeof FlipperPlugin | typeof FlipperDevicePlugin; type PluginClass = typeof FlipperPlugin | typeof FlipperDevicePlugin;
export type RegisterPluginAction = {
type: 'REGISTER_PLUGINS';
payload: Array<PluginClass>;
};
export type Action = export type Action =
| { | RegisterPluginAction
type: 'REGISTER_PLUGINS';
payload: Array<P>;
}
| { | {
type: 'GATEKEEPED_PLUGINS'; type: 'GATEKEEPED_PLUGINS';
payload: Array<PluginDefinition>; payload: Array<PluginDefinition>;
@@ -61,7 +63,7 @@ export default function reducer(
if (action.type === 'REGISTER_PLUGINS') { if (action.type === 'REGISTER_PLUGINS') {
return produce(state, draft => { return produce(state, draft => {
const {devicePlugins, clientPlugins} = draft; const {devicePlugins, clientPlugins} = draft;
action.payload.forEach((p: P) => { action.payload.forEach((p: PluginClass) => {
if (devicePlugins.has(p.id) || clientPlugins.has(p.id)) { if (devicePlugins.has(p.id) || clientPlugins.has(p.id)) {
return; return;
} }
@@ -105,7 +107,7 @@ export const selectedPlugins = (payload: Array<string>): Action => ({
payload, payload,
}); });
export const registerPlugins = (payload: Array<P>): Action => ({ export const registerPlugins = (payload: Array<PluginClass>): Action => ({
type: 'REGISTER_PLUGINS', type: 'REGISTER_PLUGINS',
payload, payload,
}); });