diff --git a/src/App.tsx b/src/App.tsx index f58d2d9ed..008c99c99 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -19,7 +19,6 @@ import ShareSheetExportUrl from './chrome/ShareSheetExportUrl'; import SignInSheet from './chrome/SignInSheet'; import ExportDataPluginSheet from './chrome/ExportDataPluginSheet'; import ShareSheetExportFile from './chrome/ShareSheetExportFile'; -import JSEmulatorLauncherSheet from './chrome/JSEmulatorLauncherSheet'; import PluginContainer from './PluginContainer'; import Sheet from './chrome/Sheet'; import {ipcRenderer, remote} from 'electron'; @@ -35,7 +34,6 @@ import { ACTIVE_SHEET_SHARE_DATA_IN_FILE, ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT, ACTIVE_SHEET_PLUGIN_SHEET, - ACTIVE_SHEET_JS_EMULATOR_LAUNCHER, } from './reducers/application'; import {Logger} from './fb-interfaces/Logger'; import BugReporter from './fb-stubs/BugReporter'; @@ -124,8 +122,6 @@ export class App extends React.Component { case ACTIVE_SHEET_PLUGIN_SHEET: // Currently unused. return null; - case ACTIVE_SHEET_JS_EMULATOR_LAUNCHER: - return ; default: return null; } diff --git a/src/Client.tsx b/src/Client.tsx index 2dfce3c38..db2842600 100644 --- a/src/Client.tsx +++ b/src/Client.tsx @@ -13,8 +13,7 @@ import {App} from './App.js'; import {Logger} from './fb-interfaces/Logger'; import {Store} from './reducers/index'; import {setPluginState} from './reducers/pluginStates'; -import {Payload, ConnectionStatus} from 'rsocket-types'; -import {Flowable, Single} from 'rsocket-flowable'; +import {ReactiveSocket} from 'rsocket-types'; import {performance} from 'perf_hooks'; import {reportPlatformFailures, reportPluginFailures} from './utils/metrics'; import {notNull} from './utils/typeUtils'; @@ -98,13 +97,6 @@ const handleError = ( } }; -export interface FlipperClientConnection { - connectionStatus(): Flowable; - close(): void; - fireAndForget(payload: Payload): void; - requestResponse(payload: Payload): Single>; -} - export default class Client extends EventEmitter { app: App | undefined; connected: boolean; @@ -113,7 +105,7 @@ export default class Client extends EventEmitter { sdkVersion: number; messageIdCounter: number; plugins: Plugins; - connection: FlipperClientConnection | null | undefined; + connection: ReactiveSocket | null | undefined; store: Store; activePlugins: Set; device: Promise; @@ -137,7 +129,7 @@ export default class Client extends EventEmitter { constructor( id: string, query: ClientQuery, - conn: FlipperClientConnection | null | undefined, + conn: ReactiveSocket | null | undefined, logger: Logger, store: Store, plugins?: Plugins | null | undefined, diff --git a/src/chrome/DevicesButton.tsx b/src/chrome/DevicesButton.tsx index f027a67f9..a27ccf988 100644 --- a/src/chrome/DevicesButton.tsx +++ b/src/chrome/DevicesButton.tsx @@ -12,17 +12,11 @@ import {connect, ReactReduxContext} from 'react-redux'; import {spawn} from 'child_process'; import {dirname} from 'path'; import {selectDevice, preferDevice} from '../reducers/connections'; -import { - setActiveSheet, - ActiveSheet, - ACTIVE_SHEET_JS_EMULATOR_LAUNCHER, -} from '../reducers/application'; import {default as which} from 'which'; import {showOpenDialog} from '../utils/exportData'; import BaseDevice from '../devices/BaseDevice'; import React, {Component} from 'react'; import {State} from '../reducers'; -import GK from '../fb-stubs/GK'; type StateFromProps = { selectedDevice: BaseDevice | null | undefined; @@ -33,7 +27,6 @@ type StateFromProps = { type DispatchFromProps = { selectDevice: (device: BaseDevice) => void; preferDevice: (device: string) => void; - setActiveSheet: (sheet: ActiveSheet) => void; }; type OwnProps = {}; @@ -161,30 +154,17 @@ class DevicesButton extends Component { label: name, click: () => this.launchEmulator(name), })); - - // Launch JS emulator - if (GK.get('flipper_js_client_emulator')) { - if (emulators.length > 0) { - dropdown.push( - {type: 'separator' as 'separator'}, - { - label: 'Launch Android emulators', - enabled: false, - }, - ...emulators, - ); - } + if (emulators.length > 0) { dropdown.push( {type: 'separator' as 'separator'}, { - label: 'Launch JS Web App', - click: () => - this.props.setActiveSheet(ACTIVE_SHEET_JS_EMULATOR_LAUNCHER), + label: 'Launch Android emulators', + enabled: false, }, + ...emulators, ); } } - if (dropdown.length > 0) { dropdown.push({type: 'separator' as 'separator'}); } @@ -216,6 +196,5 @@ export default connect( { selectDevice, preferDevice, - setActiveSheet, }, )(DevicesButton); diff --git a/src/chrome/JSEmulatorLauncherSheet.tsx b/src/chrome/JSEmulatorLauncherSheet.tsx deleted file mode 100644 index 9cca353e6..000000000 --- a/src/chrome/JSEmulatorLauncherSheet.tsx +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -import { - FlexColumn, - Button, - styled, - Text, - FlexRow, - Spacer, - Input, - Label, -} from 'flipper'; -import React, {Component} from 'react'; -import {connect} from 'react-redux'; -import {State as Store} from '../reducers'; -import {launchJsEmulator} from '../utils/js-client/serverUtils'; - -const Container = styled(FlexColumn)({ - padding: 20, - width: 800, -}); - -const Title = styled(Text)({ - marginBottom: 18, - marginRight: 10, - fontWeight: 100, - fontSize: '40px', -}); - -const textareaStyle = { - margin: 0, - marginBottom: 10, -}; - -const TitleInput = styled(Input)({ - ...textareaStyle, - height: 30, -}); - -type OwnProps = { - onHide: () => void; -}; - -type StateFromProps = {}; - -type DispatchFromProps = {}; - -type State = { - url: string; - width: number; - height: number; -}; - -type Props = OwnProps & StateFromProps & DispatchFromProps; -class JSEmulatorLauncherSheet extends Component { - state: State = { - url: 'http://localhost:8888', - width: 800, - height: 600, - }; - - onUrlChange = (e: React.ChangeEvent) => { - this.setState({url: e.target.value}); - }; - - onHeightChange = (e: React.ChangeEvent) => { - this.setState({height: Number(e.target.value)}); - }; - - onWidthChange = (e: React.ChangeEvent) => { - this.setState({width: Number(e.target.value)}); - }; - - render() { - const {url, height, width} = this.state; - return ( - - Launch Web App - - - - - - - -
- - - - - -
- ); - } -} - -export default connect( - () => ({}), - {}, -)(JSEmulatorLauncherSheet); diff --git a/src/devices/BaseDevice.tsx b/src/devices/BaseDevice.tsx index 4de942deb..a767495ca 100644 --- a/src/devices/BaseDevice.tsx +++ b/src/devices/BaseDevice.tsx @@ -52,7 +52,7 @@ export type DeviceExport = { logs: Array; }; -export type OS = 'iOS' | 'Android' | 'Windows' | 'MacOS' | 'JSWebApp'; +export type OS = 'iOS' | 'Android' | 'Windows' | 'MacOS'; export default class BaseDevice { constructor(serial: string, deviceType: DeviceType, title: string, os: OS) { diff --git a/src/devices/JSDevice.tsx b/src/devices/JSDevice.tsx deleted file mode 100644 index b5691739e..000000000 --- a/src/devices/JSDevice.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -import BaseDevice from './BaseDevice'; - -export default class JSDevice extends BaseDevice { - webContentsId: number; - - constructor(serial: string, title: string, webContentsId: number) { - super(serial, 'emulator', title, 'JSWebApp'); - this.devicePlugins = []; - this.webContentsId = webContentsId; - } -} diff --git a/src/reducers/application.tsx b/src/reducers/application.tsx index db0ecb2f4..562c6a10f 100644 --- a/src/reducers/application.tsx +++ b/src/reducers/application.tsx @@ -26,8 +26,6 @@ export const ACTIVE_SHEET_SHARE_DATA_IN_FILE: 'SHARE_DATA_IN_FILE' = export const SET_EXPORT_STATUS_MESSAGE: 'SET_EXPORT_STATUS_MESSAGE' = 'SET_EXPORT_STATUS_MESSAGE'; export const UNSET_SHARE: 'UNSET_SHARE' = 'UNSET_SHARE'; -export const ACTIVE_SHEET_JS_EMULATOR_LAUNCHER: 'ACTIVE_SHEET_JS_EMULATOR_LAUNCHER' = - 'ACTIVE_SHEET_JS_EMULATOR_LAUNCHER'; export type ActiveSheet = | typeof ACTIVE_SHEET_PLUGIN_SHEET @@ -39,7 +37,6 @@ export type ActiveSheet = | typeof ACTIVE_SHEET_DOCTOR | typeof ACTIVE_SHEET_SHARE_DATA_IN_FILE | typeof ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT - | typeof ACTIVE_SHEET_JS_EMULATOR_LAUNCHER | null; export type LauncherMsg = { diff --git a/src/server.tsx b/src/server.tsx index 1e15ce557..b1cdbe0a1 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -16,7 +16,6 @@ import {RSocketServer} from 'rsocket-core'; import RSocketTCPServer from 'rsocket-tcp-server'; import {Single} from 'rsocket-flowable'; import Client from './Client'; -import {FlipperClientConnection} from './Client'; import {UninitializedClient} from './UninitializedClient'; import {reportPlatformFailures} from './utils/metrics'; import EventEmitter from 'events'; @@ -24,11 +23,9 @@ import invariant from 'invariant'; import tls from 'tls'; import net, {Socket} from 'net'; import {Responder, Payload, ReactiveSocket} from 'rsocket-types'; -import GK from './fb-stubs/GK'; -import {initJsEmulatorIPC} from './utils/js-client/serverUtils'; type ClientInfo = { - connection: FlipperClientConnection | null | undefined; + connection: ReactiveSocket | null | undefined; client: Client; }; @@ -86,11 +83,6 @@ class Server extends EventEmitter { return; }); reportPlatformFailures(this.initialisePromise, 'initializeServer'); - - if (GK.get('flipper_js_client_emulator')) { - initJsEmulatorIPC(this.store, this.logger, this, this.connections); - } - return this.initialisePromise; } @@ -311,7 +303,7 @@ class Server extends EventEmitter { } async addConnection( - conn: FlipperClientConnection, + conn: ReactiveSocket, query: ClientQuery, csrQuery: ClientCsrQuery, ): Promise { diff --git a/src/utils/js-client/serverUtils.tsx b/src/utils/js-client/serverUtils.tsx deleted file mode 100644 index b31f8ffe6..000000000 --- a/src/utils/js-client/serverUtils.tsx +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -import Client, {ClientQuery} from '../../Client'; -import {FlipperClientConnection} from '../../Client'; -import {ipcRenderer, remote} from 'electron'; -import JSDevice from '../../devices/JSDevice'; -import {Store} from 'src/reducers'; -import {Logger} from 'src/fb-interfaces/Logger'; - -import {Payload, ConnectionStatus, ISubscriber} from 'rsocket-types'; -import {Flowable, Single} from 'rsocket-flowable'; -import Server from 'src/server'; - -const connections: Map> = new Map(); - -const availablePlugins: Map> = new Map(); - -function jsDeviceId(windowId: number): string { - return 'test_js_device' + windowId; -} - -export function initJsEmulatorIPC( - store: Store, - logger: Logger, - flipperServer: Server, - flipperConnections: Map< - string, - { - connection: FlipperClientConnection | null | undefined; - client: Client; - } - >, -) { - ipcRenderer.on('from-js-emulator-init-client', (_event, message) => { - const {windowId} = message; - const {plugins, appName} = message.payload; - store.dispatch({ - type: 'REGISTER_DEVICE', - payload: new JSDevice(jsDeviceId(windowId), 'jsEmulator', windowId), - }); - - const connection = new JSClientFlipperConnection(windowId); - connections.set(windowId, connection); - availablePlugins.set(windowId, plugins); - - const query: ClientQuery = { - app: appName, - os: 'JSWebApp', - device: 'jsEmulator', - device_id: jsDeviceId(windowId), - sdk_version: 2, // hack to bybass callbacks in Client, will be fixed when JS Connection will be fully implemented - }; - const clientId = `${query.app}#${query.os}#${query.device}#${query.device_id}`; - - const client = new Client( - clientId, - query, - connection, - logger, - store, - plugins, - ); - - flipperConnections.set(clientId, {connection: connection, client: client}); - - connection.connectionStatus().subscribe({ - onNext(payload) { - if (payload.kind == 'ERROR' || payload.kind == 'CLOSED') { - console.debug(`Device disconnected ${client.id}`, 'server'); - flipperServer.removeConnection(client.id); - const toUnregister = new Set(); - toUnregister.add(jsDeviceId(windowId)); - store.dispatch({ - type: 'UNREGISTER_DEVICES', - payload: toUnregister, - }); - connections.delete(windowId); - availablePlugins.delete(windowId); - } - }, - onSubscribe(subscription) { - subscription.request(Number.MAX_SAFE_INTEGER); - }, - }); - - client.init().then(() => { - console.log(client); - flipperServer.emit('new-client', client); - flipperServer.emit('clients-change'); - client.emit('plugins-change'); - - ipcRenderer.on('from-js-emulator', (_event, message) => { - const {command, payload} = message; - if (command === 'sendFlipperObject') { - client.onMessage( - JSON.stringify({ - params: { - api: payload.api, - method: payload.method, - params: JSON.parse(payload.params), - }, - method: 'execute', - }), - ); - } - }); - }); - }); -} - -export function launchJsEmulator(url: string, height: number, width: number) { - const BrowserWindow = remote.BrowserWindow; - const win = new BrowserWindow({ - height: height, - width: width, - webPreferences: { - preload: require('path').join( - remote.app.getAppPath(), - 'SupportJSClientPreload.js', - ), - nodeIntegration: false, - contextIsolation: false, - allowRunningInsecureContent: true, - }, - }); - - win.webContents.on('preload-error', (_event, path, error) => { - console.log(path, error); - }); - - win.loadURL(url); - - win.webContents.on('did-finish-load', () => { - win.webContents.send('parent-window-id', remote.getCurrentWebContents().id); - - const childWindowId = win.webContents.id; - win.on('closed', () => { - connections.get(childWindowId)?.close(); - }); - }); -} - -export class JSClientFlipperConnection - implements FlipperClientConnection { - webContentsId: number; - connStatusSubscribers: Set> = new Set(); - connStatus: ConnectionStatus; - - constructor(webContentsId: number) { - this.webContentsId = webContentsId; - this.connStatus = {kind: 'CONNECTED'}; - } - - connectionStatus(): Flowable { - return new Flowable(subscriber => { - subscriber.onSubscribe({ - cancel: () => { - this.connStatusSubscribers.delete(subscriber); - }, - request: _ => { - this.connStatusSubscribers.add(subscriber); - subscriber.onNext(this.connStatus); - }, - }); - }); - } - - close(): void { - this.connStatus = {kind: 'CLOSED'}; - this.connStatusSubscribers.forEach(subscriber => { - subscriber.onNext(this.connStatus); - }); - } - - fireAndForget(payload: Payload): void { - ipcRenderer.sendTo( - this.webContentsId, - 'message-to-plugin', - JSON.parse(payload.data != null ? payload.data : '{}'), - ); - } - - // TODO: fully implement and return actual result - requestResponse(payload: Payload): Single> { - return new Single(subscriber => { - const method = - payload.data != null ? JSON.parse(payload.data).method : 'not-defined'; - if (method != 'getPlugins') { - this.fireAndForget(payload); - } - subscriber.onSubscribe(() => {}); - subscriber.onComplete( - method == 'getPlugins' - ? { - data: JSON.stringify({ - success: {plugins: availablePlugins.get(this.webContentsId)}, - }), - } - : {data: JSON.stringify({success: null})}, - ); - }); - } -} diff --git a/static/SupportJSClientPreload.js b/static/SupportJSClientPreload.js deleted file mode 100644 index 93dca57cb..000000000 --- a/static/SupportJSClientPreload.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -// ============== -// Preload script -// ============== -const {remote, ipcRenderer} = require('electron'); - -let FlipperMainWindowId = 0; - -ipcRenderer.on('parent-window-id', (event, message) => { - FlipperMainWindowId = message; -}); - -let FlipperIsClientInit = false; -let FlipperMemoizedPlugins; - -function initClient(plugins) { - if (FlipperIsClientInit) { - return; - } - if (plugins) { - FlipperMemoizedPlugins = plugins; - } - if (FlipperMainWindowId != 0) { - ipcRenderer.sendTo(FlipperMainWindowId, 'from-js-emulator-init-client', { - command: 'initClient', - windowId: remote.getCurrentWebContents().id, - payload: { - plugins: plugins ? plugins : FlipperMemoizedPlugins, - appName: 'kite/weblite', - }, - }); - FlipperIsClientInit = true; - } -} - -window.FlipperWebviewBridge = { - registerPlugins: function(plugins) { - console.log(plugins); - if (FlipperMainWindowId != 0) { - ipcRenderer.sendTo(FlipperMainWindowId, 'from-js-emulator', { - command: 'registerPlugins', - payload: plugins, - }); - } - }, - start: function() { - console.log('start'); - - if (FlipperMainWindowId != 0) { - ipcRenderer.sendTo(FlipperMainWindowId, 'from-js-emulator', { - command: 'start', - payload: null, - }); - } - }, - sendFlipperObject: function(plugin, method, data) { - console.log(plugin, method, data); - initClient(); - if (FlipperMainWindowId != 0) { - ipcRenderer.sendTo(FlipperMainWindowId, 'from-js-emulator', { - command: 'sendFlipperObject', - payload: { - api: plugin, - method: method, - params: data, - }, - }); - } - }, - isFlipperSupported: true, - initClient: initClient, -}; - -ipcRenderer.on('message-to-plugin', (event, message) => { - const flipper = window.flipper; - if (!flipper) { - return; - } - const receiver = flipper.FlipperWebviewMessageReceiver.receive; - const {api, method, params} = message.params; - receiver(api, method, JSON.stringify(params)); -});