Reload single device plugin on auto-update
Summary: The same as D23729972 (0982dc06a0), but now it is also possible to reload device plugins independently.
Reviewed By: jknoxville
Differential Revision: D23960058
fbshipit-source-id: 01e0edb29a62ed173dfe6f5946466269adee453a
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1b4c08b282
commit
80c7c76ef9
@@ -242,9 +242,10 @@ class MainSidebar2 extends PureComponent<Props, State> {
|
|||||||
selectedDevice,
|
selectedDevice,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const clients = getAvailableClients(device, this.props.clients);
|
const clients = getAvailableClients(device, this.props.clients);
|
||||||
const devicePluginsItems = device.devicePlugins.map((pluginName) => {
|
const devicePluginsItems = device.devicePlugins
|
||||||
const plugin = this.props.devicePlugins.get(pluginName)!;
|
.map((pluginName) => this.props.devicePlugins.get(pluginName)!)
|
||||||
return (
|
.sort(sortPluginsByName)
|
||||||
|
.map((plugin) => (
|
||||||
<PluginSidebarListItem
|
<PluginSidebarListItem
|
||||||
key={plugin.id}
|
key={plugin.id}
|
||||||
isActive={plugin.id === selectedPlugin && selectedDevice === device}
|
isActive={plugin.id === selectedPlugin && selectedDevice === device}
|
||||||
@@ -258,8 +259,7 @@ class MainSidebar2 extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
plugin={plugin}
|
plugin={plugin}
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
const wrapDevicePlugins =
|
const wrapDevicePlugins =
|
||||||
clients.length > 0 && device.devicePlugins.length > 1 && !device.source;
|
clients.length > 0 && device.devicePlugins.length > 1 && !device.source;
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,13 @@
|
|||||||
|
|
||||||
import stream from 'stream';
|
import stream from 'stream';
|
||||||
import type {DeviceLogListener} from 'flipper';
|
import type {DeviceLogListener} from 'flipper';
|
||||||
import {sortPluginsByName} from '../utils/pluginUtils';
|
|
||||||
import {
|
import {
|
||||||
DeviceLogEntry,
|
DeviceLogEntry,
|
||||||
SandyDevicePluginInstance,
|
SandyDevicePluginInstance,
|
||||||
SandyPluginDefinition,
|
SandyPluginDefinition,
|
||||||
DeviceType,
|
DeviceType,
|
||||||
} from 'flipper-plugin';
|
} from 'flipper-plugin';
|
||||||
import type {DevicePluginMap, FlipperDevicePlugin} from '../plugin';
|
import type {DevicePluginDefinition, DevicePluginMap} from '../plugin';
|
||||||
import {getFlipperLibImplementation} from '../utils/flipperLibImplementation';
|
import {getFlipperLibImplementation} from '../utils/flipperLibImplementation';
|
||||||
|
|
||||||
export type DeviceShell = {
|
export type DeviceShell = {
|
||||||
@@ -170,13 +169,12 @@ export default class BaseDevice {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const plugins = Array.from(devicePlugins.values());
|
const plugins = Array.from(devicePlugins.values());
|
||||||
plugins.sort(sortPluginsByName);
|
|
||||||
for (const plugin of plugins) {
|
for (const plugin of plugins) {
|
||||||
this.loadDevicePlugin(plugin);
|
this.loadDevicePlugin(plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDevicePlugin(plugin: typeof FlipperDevicePlugin | SandyPluginDefinition) {
|
loadDevicePlugin(plugin: DevicePluginDefinition) {
|
||||||
if (plugin instanceof SandyPluginDefinition) {
|
if (plugin instanceof SandyPluginDefinition) {
|
||||||
if (plugin.asDevicePluginModule().supportsDevice(this as any)) {
|
if (plugin.asDevicePluginModule().supportsDevice(this as any)) {
|
||||||
this.devicePlugins.push(plugin.id);
|
this.devicePlugins.push(plugin.id);
|
||||||
@@ -195,4 +193,13 @@ export default class BaseDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unloadDevicePlugin(pluginId: string) {
|
||||||
|
const instance = this.sandyPluginStates.get(pluginId);
|
||||||
|
if (instance) {
|
||||||
|
instance.destroy();
|
||||||
|
this.sandyPluginStates.delete(pluginId);
|
||||||
|
}
|
||||||
|
this.devicePlugins.splice(this.devicePlugins.indexOf(pluginId), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,15 @@ import {
|
|||||||
isDevicePluginDefinition,
|
isDevicePluginDefinition,
|
||||||
} from './utils/pluginUtils';
|
} from './utils/pluginUtils';
|
||||||
import Client from './Client';
|
import Client from './Client';
|
||||||
import {PluginDefinition} from './plugin';
|
import {
|
||||||
|
DevicePluginDefinition,
|
||||||
|
FlipperPlugin,
|
||||||
|
PluginDefinition,
|
||||||
|
} from './plugin';
|
||||||
import {deconstructPluginKey} from './utils/clientUtils';
|
import {deconstructPluginKey} from './utils/clientUtils';
|
||||||
|
import {SandyPluginDefinition} from 'flipper-plugin';
|
||||||
|
import BaseDevice from './devices/BaseDevice';
|
||||||
|
import {State as PluginStates} from './reducers/pluginStates';
|
||||||
|
|
||||||
export const store: Store = createStore<StoreState, Actions, any, any>(
|
export const store: Store = createStore<StoreState, Actions, any, any>(
|
||||||
rootReducer,
|
rootReducer,
|
||||||
@@ -69,42 +76,12 @@ export function rootReducer(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (action.type === 'UPDATE_PLUGIN' && state) {
|
} else if (action.type === 'UPDATE_PLUGIN' && state) {
|
||||||
const plugin: PluginDefinition = action.payload;
|
const plugin = action.payload;
|
||||||
const clients = state.connections.clients;
|
if (isDevicePluginDefinition(plugin)) {
|
||||||
return produce(state, (draft) => {
|
return updateDevicePlugin(state, plugin);
|
||||||
const clientsWithEnabledPlugin = clients.filter((c) => {
|
} else {
|
||||||
return (
|
return updateClientPlugin(state, plugin);
|
||||||
c.supportsPlugin(plugin.id) &&
|
}
|
||||||
state.connections.userStarredPlugins[c.query.app]?.includes(plugin.id)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// stop plugin for each client where it is enabled
|
|
||||||
clientsWithEnabledPlugin.forEach((client) => {
|
|
||||||
stopPlugin(client, plugin.id, true);
|
|
||||||
delete draft.pluginMessageQueue[
|
|
||||||
getPluginKey(client.id, {serial: client.query.device_id}, plugin.id)
|
|
||||||
];
|
|
||||||
});
|
|
||||||
// cleanup classic plugin state
|
|
||||||
Object.keys(draft.pluginStates).forEach((pluginKey) => {
|
|
||||||
const pluginKeyParts = deconstructPluginKey(pluginKey);
|
|
||||||
if (pluginKeyParts.pluginName === plugin.id) {
|
|
||||||
delete draft.pluginStates[pluginKey];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// update plugin definition
|
|
||||||
const {devicePlugins, clientPlugins} = draft.plugins;
|
|
||||||
const p = action.payload;
|
|
||||||
if (isDevicePluginDefinition(p)) {
|
|
||||||
devicePlugins.set(p.id, p);
|
|
||||||
} else {
|
|
||||||
clientPlugins.set(p.id, p);
|
|
||||||
}
|
|
||||||
// start plugin for each client
|
|
||||||
clientsWithEnabledPlugin.forEach((client) => {
|
|
||||||
startPlugin(client, plugin, true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise
|
// otherwise
|
||||||
@@ -149,3 +126,66 @@ function startPlugin(
|
|||||||
client.initPlugin(plugin.id);
|
client.initPlugin(plugin.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateClientPlugin(state: StoreState, plugin: typeof FlipperPlugin) {
|
||||||
|
const clients = state.connections.clients;
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
const clientsWithEnabledPlugin = clients.filter((c) => {
|
||||||
|
return (
|
||||||
|
c.supportsPlugin(plugin.id) &&
|
||||||
|
state.connections.userStarredPlugins[c.query.app]?.includes(plugin.id)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// stop plugin for each client where it is enabled
|
||||||
|
clientsWithEnabledPlugin.forEach((client) => {
|
||||||
|
stopPlugin(client, plugin.id, true);
|
||||||
|
delete draft.pluginMessageQueue[
|
||||||
|
getPluginKey(client.id, {serial: client.query.device_id}, plugin.id)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
cleanupPluginStates(draft.pluginStates, plugin.id);
|
||||||
|
// update plugin definition
|
||||||
|
draft.plugins.clientPlugins.set(plugin.id, plugin);
|
||||||
|
// start plugin for each client
|
||||||
|
clientsWithEnabledPlugin.forEach((client) => {
|
||||||
|
startPlugin(client, plugin, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDevicePlugin(state: StoreState, plugin: DevicePluginDefinition) {
|
||||||
|
const devices = state.connections.devices;
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
const devicesWithEnabledPlugin = devices.filter((d) =>
|
||||||
|
supportsDevice(plugin, d),
|
||||||
|
);
|
||||||
|
devicesWithEnabledPlugin.forEach((d) => {
|
||||||
|
d.unloadDevicePlugin(plugin.id);
|
||||||
|
});
|
||||||
|
cleanupPluginStates(draft.pluginStates, plugin.id);
|
||||||
|
draft.plugins.devicePlugins.set(plugin.id, plugin);
|
||||||
|
devicesWithEnabledPlugin.forEach((d) => {
|
||||||
|
d.loadDevicePlugin(plugin);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function supportsDevice(plugin: DevicePluginDefinition, device: BaseDevice) {
|
||||||
|
if (plugin instanceof SandyPluginDefinition) {
|
||||||
|
return (
|
||||||
|
plugin.isDevicePlugin &&
|
||||||
|
plugin.asDevicePluginModule().supportsDevice(device as any)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return plugin.supportsDevice(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanupPluginStates(pluginStates: PluginStates, pluginId: string) {
|
||||||
|
Object.keys(pluginStates).forEach((pluginKey) => {
|
||||||
|
const pluginKeyParts = deconstructPluginKey(pluginKey);
|
||||||
|
if (pluginKeyParts.pluginName === pluginId) {
|
||||||
|
delete pluginStates[pluginKey];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user