Summary:
Client up `client.device` (which had no code references anymore) / `client.deviceSync`. Cleaned up feature code for old SDKs (pre 2, which is 3 years old).
This makes decapitating Client a little simpler in the rest of the stack.
Reviewed By: passy
Differential Revision: D31235436
fbshipit-source-id: 919679c1830e2b9368d0787d7b363c090305edb8
Summary:
This stack takes care of handling care of moving all device interactions over the (possible) async channel FlipperServer. The FlipperServer interface (see previous diff) allows listening to specific server events using `on`, and emit commands to be executed by the server by using `exec` (e.g. `exec('take-screenshot', serial) => Promise<buffer>`).
FlipperServerImpl implements this interface on the server side.
The device implementations are split as follows
```
server / backend process:
ServerDevice
- iOSDevice
- AndroidDevice
- MetroDevice
- DummyDevice
- Mac/Windows Device
frontend / ui:
BaseDevice: a normal connected, device, implements device apis as they already existed
- ArchivedDevice (note that this doesn't have a server counterpart)
- TestDevice (for unit tests, with stubbed backend communication)
```
All features of devices are for simplicity unified (since the deviations are small), where specific device types might not implement certain features like taking screenshots or running shell commands.
To avoid making this diff unnecessarily big, some open Todo's will be addressed later in this stack, and it shouldn't be landed alone.
Reviewed By: timur-valiev
Differential Revision: D30909346
fbshipit-source-id: cce0bee94fdd5db59bebe3577a6084219a038719
Summary:
This is the first of many diffs that extracts the connection, device, client detection out of the flipper core, to create a reusable flipper-server library that can be used in e.g. flipper-dump.
To keep diffs a little smaller, the current connection logic is first moved to the `server/` directory, and decoupled manually from the rest of the core, before moving it over to a separate package.
This first diffs moves the `comms/`, `devices/` and certificate utilities to the `server` directory.
Further untangling will follow in next diffs
Reviewed By: timur-valiev
Differential Revision: D30246551
fbshipit-source-id: c84259bfb1239119b3267a51b015e30c3c080866
Summary:
This removes all code duplication / old plugin infra that isn't needed anymore when all plugin run on the Sandy plugin infra structure.
The diff is quite large, but the minimal one that passes tests and compiles. Existing tests are preserved by wrapping all remaining tests in `wrapSandy` for classic plugins where needed
Reviewed By: passy
Differential Revision: D29394738
fbshipit-source-id: 1315fabd9f048576aed15ed5f1cb6414d5fdbd40
Summary:
Changelog: [Flipper] Improve serialisation mechanism format & speed
The default serialisation mechanism used by Flipper to serialise plugin states is very flexible, taking care of maps, sets, dates etc. However, it is also really slow, leading to issues like in the related tasks, and work arounds like D17402443 (98bc01618f) to skip the whole process for plugins.
This diff changes the serialisation mechanism to have a better trade off between speed and convenience: For now we will only apply the smart serialisation for objects living at the _root_ of the serialised object, but it won't be applied recursively.
This sounds like a dangerous change, but works well in practice:
* I went through all `persistedState` and `createState` definition (the types), and the idea that complex types like Map and Set only live at the root of the persisted state holds up nicely. That makes sense as well since plugins typically store literally the same data as that they have received over the wire, except that they put it in some maps, sets etc.
* I introduced `assertSerializable` that only runs in dev/test, which will check (recursively, but without all the cloning) to see if a tree is indeed serialisable.
* The fact that by swapping this mechanism rarely existing unit test for exportData needed changes proves that the assumption that only roots are relevant generally upholds (or that plugin authors don't write enough tests ;-)).
* I verified that popular plugins still import / export correctly (actually *more* plugins are exportable now than before, thanks to sandy wrapper introduced earlier)
Reviewed By: jknoxville
Differential Revision: D29327499
fbshipit-source-id: 0ff17d9c5eb68fccfc2937b634cfa8f4f924247d
Summary:
This diff introduces loading classic Flipper plugins in a Sandy container. By wrapping plugins into Sandy we will be able to remove a lot of code / logic duplication related to state, queue processing, serialization etc. This will allow us to remove most or all of the complex plugin logic from the old system, only keeping onto the legacy components which have a lower maintenance burden. Until all plugins are Sandy.
This diff is not feature complete but only implements the core mechanisms for (persisted) state and communication.
Keyboard support, serialization, and rewiring tests etc will be added in next diff.
The feature is introduced behind GK flipper_use_sandy_plugin_wrapper to have kill switch.
Tests will be added later in this diff by redirection a part of the current mechanisms to wrapped plugins. (Will land the stack as a whole)
Reviewed By: passy
Differential Revision: D29165866
fbshipit-source-id: 57f84794a4a5f898bf765ce2de13cc759267fbc6
Summary: `onRegisterDevice` device abstraction was only used by the CrashReporterPlugin, and since with Sandy plugin lifecycles every plugin can do 'on-load' logic, we don't need it anymore.
Reviewed By: priteshrnandgaonkar
Differential Revision: D27046711
fbshipit-source-id: 16c567c60ed29a50017d525a2b707ee696a99e62
Summary: Exposed the `pluginKey` to sandy plugins (which we will use later for storing table preferences per plugin). And a little moving code around because circular deps problem roared its ugly head again.
Reviewed By: nikoant
Differential Revision: D27009721
fbshipit-source-id: 7ad29e72ff8028c9daae270c4749b657bd8ff049
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*: changed the way how plugin compatibility with devices is checked from dynamic call to "supportsDevice" to static checks of "supportedDevices" metadata property which make it possible to check compatibility without even downloading plugin from Marketplace.
Changelog: plugin compatibility with devices is now checked according to metadata in property "supportedDevices" in package.json
Reviewed By: mweststrate
Differential Revision: D26315848
fbshipit-source-id: 6e4b052c4ea0507ee185fc17999b6211cdb11093
Summary:
This diff addresses two problems:
1. Since clients plugins can be active beyond having a connection, we have to make it possible for plugin authors to check if they are connected before they make a call.
2. if there is a custom `exportPersistedState`, plugins should be able to skip making calls if the device has disconnected.
Introducing this change makes it possible to interact with a reasonable level with disconnected clients, and makes it possible to create Flipper traces for disconnected clients.
Note that both items were already problems before supporting offline clients; as there can be a noticeable delay between disconnecting and Flipper detecting that (i've seen up to 30 secs). What happend previously in those cases is that the export would simply hang, as would other user interactions, as loosing the connection in the middle of a process would cause the promise chains to be neither rejected or resolved, which is pretty iffy.
Before this diff, trying to export a disconnected device would hang forever like:
{F369600601}
Reviewed By: nikoant
Differential Revision: D26250895
fbshipit-source-id: 177624a116883c3cba14390cd0fe164e243bb97c
Summary:
Sandy plugins can now set up an `onExport` handler to enable customizing the export format of a plugin: `client.onExport(callback: (idler, onStatusMessage) => Promise<state>)`
Import will be done in next diff
Reviewed By: nikoant
Differential Revision: D26124440
fbshipit-source-id: c787c79d929aa8fb484f15a9340d7c87545793cb
Summary:
I've re-designed interfaces describing plugins as I found that mental overhead working with them became too expensive because of slightly flawed design. However this cascaded changes in many files so you can see how extensively these interfaces used in our codebase.
Before this change we had one interface PluginDetails which described three different entities: 1) plugins installed on the disk 2) plugins bundled into Flipper 3) plugins available on Marketplace. It's hard to use this "general" PluginDetails interface because of this as you always need to think about all three use cases everywhere.
After this change we have 3 separate interfaces: InstalledPluginDetails, BundledPluginDetails and DownloadablePluginDetails and things became much type-safer now.
Reviewed By: mweststrate
Differential Revision: D25530383
fbshipit-source-id: b93593916a980c04e36dc6ffa168797645a0ff9c
Summary: This prefixes APIs of `flipper-plugin`, that are used by Flipper, but should not be used by plugins directly, with `_`. Also added tests to make sure we are always intentional when extending the exposed APIs
Reviewed By: passy
Differential Revision: D24991700
fbshipit-source-id: ed3700efa188fca7f5a14d5c68250598cf011e42
Summary:
devices not always being readily available is causes a lot of complication in the api,
figured to resolve devices first before construction clients,
since clients not attached to a device are shown uncategorized anyway, making them practically un-interactable.
For more background info, see following chat.
{F344388883}
This diff will make it possible to only expose a synchronous api in Sandy
n.b. didn't update Navigation plugin, as that is done in a next diff
Reviewed By: jknoxville
Differential Revision: D24858332
fbshipit-source-id: 8339f831fbbc9c219add56a199364fde67adafc7
Summary:
This diffs adds support for the activeSheets mechanism in Sandy. It should be removed in the future (see T78696648) since open a dialog and keeping dialog state locally results in much more straight forward code, but supporting this for now makes sure that old flows are still supported.
With this change the plugin selection during a Flipper export for example wouldn't become visible
Reviewed By: cekkaewnumchai
Differential Revision: D24620074
fbshipit-source-id: f0558f5738e86a84a5cd0b9d574a3cfd0a3bf424
Summary:
This diff adds the rough navigation to open pugins, there are some rough egdes still, and tests will be added later, but wanted to keep diffs small, and land the feature early to get some initial dogfooding going on early.
Note that we now also show all disabled plugins to help people with trouble shooting.
Reviewed By: nikoant
Differential Revision: D24418411
fbshipit-source-id: 1402d69efe2e52bc2c81336cfb4f4c9928ea4d80
Summary:
This diff makes sure that devices will actually instantiate applicable sandy device plugins. Similar to how client plugins are owned by Client, device plugins are directly owned by BaseDevice, which significantly simplifies life cycle management and doesn't dispatch updates to all Redux connect components whenever something irrelevant changes.
Also made sure `device.teardown()` is called. That API already existed, but wasn't used or implemented before.
Updated Flipper test utils to support testing device plugins as well (both Sandy and classic ones)
Reviewed By: passy, nikoant
Differential Revision: D22693929
fbshipit-source-id: 73b2b8666ef7a0e748ea89360db84734d37eb5be
Summary:
This adds support for handling incoming deeplinks in a Sandy plugin, which can be done by using a `client.onDeepLink(deepLink => { } )` listener
Also generalized deeplinks to not just support strings, but also richer objects, which is beneficial to plugin to plugin linking.
Reviewed By: jknoxville
Differential Revision: D22524749
fbshipit-source-id: 2cbe8d52f6eac91a1c1c8c8494706952920b9181
Summary:
Made Sandy plugins part of the export / import logic
Note that in the export format there is now a `pluginStates2` field. It could have been put in `pluginStates` as well, but I started with that and it felt very weird, as the `pluginStates` are supposed to reflect what is living in the Redux stores, where sandy state doesn't live in the Redux store (not directly at least). Trying to store it in the same field made things overcomplicated and confusing.
Reviewed By: jknoxville
Differential Revision: D22432769
fbshipit-source-id: d9858e561fad4fadbf0f90858874ed444e3a836c
Summary:
Introduced hooks that are called whenever the plugin is connected / disconnected to it's counter part on the device.
There is some logic duplication between `PluginContainer` for old plugins, and `PluginRenderer` for new plugins, mostly caused by the fact that those lifecycles are triggered from the UI rather than from the reducers, but I figured refactoring that to be too risky.
Reviewed By: jknoxville
Differential Revision: D22232337
fbshipit-source-id: a384c45731a4c8d9b8b532a83e2becf49ce807c2
Summary: Replaced `instanceof` checks with `isSandyPlugin` utility. That is cleaner to read and makes it easier to find places where we make exceptions for Sandy plugins
Reviewed By: jknoxville
Differential Revision: D22206707
fbshipit-source-id: b44a1b585424f3b9bf0d7ce200c34107f03ed55e
Summary: Make sure Sandy plugins are loaded properly from disk
Reviewed By: jknoxville
Differential Revision: D22186275
fbshipit-source-id: fd2f560a7bed959b18e05db2a087909ad876ab9d
Summary:
So far there were 2 types of plugins: `FlipperPlugin` and `FlipperDevicePlugin`. This introduces a third kind: `SandyPluginDefinition`.
Unlike with the old plugins, the export of the module is not directly exposed as the plugin definition. Rather, we use class `SandyPluginDefinition` (instance) that holds a loaded definition and its meta data separately (`PluginDetails`). This means that we don't have to mix in and mutate loaded definitions, and that for unit tests we can avoid needing to provide a bunch of meta data. This also prevents a bunch of meta data existing on two places: on the loaded classes as static fields, and in the meta data field of the loaded class as well. Finally, we can now freely extends the `PluginDetails` interface in flipper, without needing to store it on the loaded classes and we are sure that no naming conflicts are caused by this in the future.
For compatibility with the existing code base, common fields are delegated from the `SandyPluginDefinition` class to the meta data.
Also cleaned up types around plugins a little bit and removed some unnecessary casts.
For all features that reason about plugins in general (such as exports), sandy plugins are ignored for now.
`SandyPluginInstance` is worked out in further diffs
The `instanceof` calls are replaced by a utility function in later diffs.
{F241363645}
Reviewed By: jknoxville
Differential Revision: D22091432
fbshipit-source-id: 3aa6b12fda5925268913779f3c3c9e84494438f8
Summary: This diff enables the installation for iOS simulators. This also fixes the error view created when there is an error. Right now there is a bug on my machine where idb doesn't detect my physical device. But once it is detected, it will work.
Reviewed By: mweststrate
Differential Revision: D22137831
fbshipit-source-id: b6d6f77318c6baef78c35af73db3969b7dd1b907
Summary:
Show notification if user has installed plugins packaged in the old format. Example text of notification:
***
Plugin "Example" will stop working after version 0.48 of Flipper released, because it is packaged using the deprecated format.
Please try to install a newer version of this plugin packaged using "Install Plugins" tab on "Manage Plugins" form.
If the latest version of the plugin is still packaged in the old format, please contact the author and consider raising a pull request for upgrading the plugin. You can find contact details on the package page https://www.npmjs.com/package/flipper-plugin-example.
If you are the author of this plugin, please migrate your plugin to the new format, and publish new version of it. See https://fbflipper.com/docs/extending/js-setup#migration-to-the-new-plugin-specification on how to migrate the plugin. See https://fbflipper.com/docs/extending/js-setup#package-format for details on plugin package format.
***
Reviewed By: passy
Differential Revision: D22065688
fbshipit-source-id: da9b9d8f62e7cdb8c926a81e24bdfb4ec67f9dff
Summary: Use interface PluginDetails everywhere where plugins are handled and removed PluginDefinition type which was effectively a subset of PluginDetails
Reviewed By: mweststrate
Differential Revision: D21927456
fbshipit-source-id: 434ebeef955b922cc11757e78fbba8dec05f1060
Summary: Download updated plugins in background. This is implemented by periodical polling of Marketplace GraphQL API (interval 5 min by default). The feature is under GK flipper_plugin_auto_update, so for now it is enabled only for me.
Reviewed By: mweststrate
Differential Revision: D21863057
fbshipit-source-id: 51d8223ad4b2a928f7571ea480c10ba2efd9935d
Summary:
Fixes https://github.com/facebook/flipper/issues/1142
When using `client.call(methodName, params)`, params has to be an object, not, for example a string.
It may work on some client implementations, e.g. iOS, but this is a coincidence and not to be relied on. If this gives you new type errors, the plugin should continue to run in the short term but has no guarantees, please adapt it to conform. You can do this by preserving backwards compatibility by doing a typecheck in your client plugin if necessary.
CHANGELOG: Calling `client.call()` or `client.send()` now fails to type-check if params is not an object, to match client implementations.
Reviewed By: nikoant
Differential Revision: D21450694
fbshipit-source-id: 53db49f874838769e39a94b1c4bd4c0b30ecdbc7
Summary:
Background for this diff: https://fb.quip.com/KqEfAlKYlgme
Some plugins don't respect that stuff (livefeed and graphql), but for others it seems to work fine.
This is just a PoC, there are some present bugs concerning the combination of selecting and bg plugins
Questions to investigate:
- [x] make sure that LiveFeed and GraphQL disconnect properly. There might be more plugins that need that
- [x] verifiy that we don't loose one of the original goals of background plugins, e.g. QPL collecting and sending data from device start. Does this still work as intended after this change?
- [x] how can we observe / measure improvements? Are dev builds more responsive after this? Is the layout inspector smoother for example because no QPL plugins are interweaved?
- [x] how is forward and backward compatibility?
- If Flipper is updated, but device not: No change I think, as getBackgroundPlugins() will return an empty set, and background plugins are initiated as usual, so old behavior
- If device is updated, but Flipper not, background plugins won't be started until they are selected. This is a degradation, but hopefully explainable.
- [x] Verify QPL buffer is not unbounded
- [x] Share architecutre changes with team
For Graphql updates: D20943455
Added runtime stats to monitor network traffic (sadly had to redo that since scuba couldn't handle the data format used at first, so probably will hold of landing this diff a week to make sure we can see some effects)
Follow up work:
[x] wait until we released the stat tracking before we release this, to be able to measure the effect?
[x] make sure graphql fix lands
[ ] use side effects abstraction
[ ] fix other background plugins (android only) or fix it in a generic way:
{F234394286}
Changelog: Background plugins will no longer receive a Flipper connection if they are disabled. This should significantly reduce the overall load of Flipper both on the device and desktop when unused plugins are disabled used, which could otherwise generate 10MB/s of network traffic certain scenarios. All plugins *should* be able to handle to this gracefully, but since this is quite a fundamental change, reach out to the Flipper team when in doubt!
Reviewed By: jknoxville
Differential Revision: D20942453
fbshipit-source-id: b699199cb95c1b3e4c36e026b6dfaee7d1652e1f
Summary:
This diff adds supportsMethod as a closure which can be used to verify a method is implemented on the client side.
It will be used in the next diff
Reviewed By: jknoxville
Differential Revision: D21176415
fbshipit-source-id: fe16d966c58d36558034ce4ade8f58f8031aab18
Summary:
Quick notes:
- This looks worse than it is. It adds mandatory parentheses to single argument lambdas. Lots of outrage on Twitter about it, personally I'm {emoji:1f937_200d_2642} about it.
- Space before function, e.g. `a = function ()` is now enforced. I like this because both were fine before.
- I added `eslint-config-prettier` to the config because otherwise a ton of rules conflict with eslint itself.
Close https://github.com/facebook/flipper/pull/915
Reviewed By: jknoxville
Differential Revision: D20594929
fbshipit-source-id: ca1c65376b90e009550dd6d1f4e0831d32cbff03
Summary:
1) moved "sonar/desktop/src" to "sonar/desktop/app/src", so "app" is now a separate package containing the core Flipper app code
2) Configured yarn workspaces with the root in "sonar/desktop": app, static, pkg, doctor, headless-tests. Plugins are not included for now, I plan to do this later.
Reviewed By: jknoxville
Differential Revision: D20535782
fbshipit-source-id: 600b2301960f37c7d72166e0d04eba462bec9fc1