From 866cb72124af310f4a8c193f086582a69afe857f Mon Sep 17 00:00:00 2001 From: John Knox Date: Thu, 15 Nov 2018 04:31:54 -0800 Subject: [PATCH] Put connection setup state in redux Summary: Puts the connection state into redux so we have more visibility on what's happening in bug reports and in general allowing us to display it on screen. Reviewed By: passy Differential Revision: D13060455 fbshipit-source-id: c79b4b7d6a1155d86128a5d8d1174ead9e4514ae --- src/UninitializedClient.js | 12 ++++++++ src/dispatcher/server.js | 28 ++++++++++++++++++ src/reducers/connections.js | 59 +++++++++++++++++++++++++++++++++++++ src/server.js | 14 +++++++++ 4 files changed, 113 insertions(+) create mode 100644 src/UninitializedClient.js diff --git a/src/UninitializedClient.js b/src/UninitializedClient.js new file mode 100644 index 000000000..c8058fa4c --- /dev/null +++ b/src/UninitializedClient.js @@ -0,0 +1,12 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export type UninitializedClient = { + os: string, + deviceName: string, + appName: string, +}; diff --git a/src/dispatcher/server.js b/src/dispatcher/server.js index dd4fa66a7..6fc6b155a 100644 --- a/src/dispatcher/server.js +++ b/src/dispatcher/server.js @@ -10,6 +10,7 @@ import Server from '../server.js'; import type {Store} from '../reducers/index.js'; import type Logger from '../fb-stubs/Logger.js'; import type Client from '../Client.js'; +import type {UninitializedClient} from '../UninitializedClient'; export default (store: Store, logger: Logger) => { const server = new Server(logger, store); @@ -45,6 +46,33 @@ export default (store: Store, logger: Logger) => { }); }); + server.addListener('start-client-setup', (client: UninitializedClient) => { + store.dispatch({ + type: 'START_CLIENT_SETUP', + payload: client, + }); + }); + + server.addListener( + 'finish-client-setup', + (payload: {client: UninitializedClient, deviceId: string}) => { + store.dispatch({ + type: 'FINISH_CLIENT_SETUP', + payload: payload, + }); + }, + ); + + server.addListener( + 'client-setup-error', + (payload: {client: UninitializedClient, error: Error}) => { + store.dispatch({ + type: 'CLIENT_SETUP_ERROR', + payload: payload, + }); + }, + ); + window.addEventListener('beforeunload', () => { server.close(); }); diff --git a/src/reducers/connections.js b/src/reducers/connections.js index 9b4a8b194..301c47f26 100644 --- a/src/reducers/connections.js +++ b/src/reducers/connections.js @@ -7,6 +7,8 @@ import type BaseDevice from '../devices/BaseDevice'; import type Client from '../Client'; +import type {UninitializedClient} from '../UninitializedClient'; +import {isEqual} from 'lodash'; export type State = {| devices: Array, @@ -19,6 +21,11 @@ export type State = {| userPreferredApp: ?string, error: ?string, clients: Array, + uninitializedClients: Array<{ + client: UninitializedClient, + deviceId?: string, + errorMessage?: string, + }>, deepLinkPayload: ?string, |}; @@ -66,6 +73,18 @@ export type Action = | { type: 'PREFER_DEVICE', payload: string, + } + | { + type: 'START_CLIENT_SETUP', + payload: UninitializedClient, + } + | { + type: 'FINISH_CLIENT_SETUP', + payload: {client: UninitializedClient, deviceId: string}, + } + | { + type: 'CLIENT_SETUP_ERROR', + payload: {client: UninitializedClient, error: Error}, }; const DEFAULT_PLUGIN = 'DeviceLogs'; @@ -81,6 +100,7 @@ const INITAL_STATE: State = { userPreferredApp: null, error: null, clients: [], + uninitializedClients: [], deepLinkPayload: null, }; @@ -208,6 +228,12 @@ export default function reducer( return { ...state, clients: state.clients.concat(payload), + uninitializedClients: state.uninitializedClients.filter(c => { + return ( + c.deviceId !== payload.query.device_id || + c.client.appName !== payload.query.app + ); + }), selectedApp, selectedPlugin, }; @@ -237,6 +263,39 @@ export default function reducer( const {payload} = action; return {...state, error: payload}; } + case 'START_CLIENT_SETUP': { + const {payload} = action; + return { + ...state, + uninitializedClients: state.uninitializedClients + .filter(entry => !isEqual(entry.client, payload)) + .concat([{client: payload}]), + }; + } + case 'FINISH_CLIENT_SETUP': { + const {payload} = action; + return { + ...state, + uninitializedClients: state.uninitializedClients.map( + c => + isEqual(c.client, payload.client) + ? {...c, deviceId: payload.deviceId} + : c, + ), + }; + } + case 'CLIENT_SETUP_ERROR': { + const {payload} = action; + return { + ...state, + uninitializedClients: state.uninitializedClients.map( + c => + isEqual(c.client, payload.client) + ? {...c, error: payload.error.message} + : c, + ), + }; + } default: return state; } diff --git a/src/server.js b/src/server.js index bbf9c09f9..46176e4ad 100644 --- a/src/server.js +++ b/src/server.js @@ -15,6 +15,7 @@ import {RSocketServer, ReactiveSocket} from 'rsocket-core'; import RSocketTCPServer from 'rsocket-tcp-server'; import {Single} from 'rsocket-flowable'; import Client from './Client.js'; +import type {UninitializedClient} from './UninitializedClient'; import {RecurringError} from './utils/errors'; const EventEmitter = (require('events'): any); @@ -140,6 +141,13 @@ export default class Server extends EventEmitter { const clientData = JSON.parse(connectRequest.data); this.connectionTracker.logConnectionAttempt(clientData); + const client: UninitializedClient = { + os: clientData.os, + deviceName: clientData.device, + appName: clientData.app, + }; + this.emit('start-client-setup', client); + if ( clientData.os === 'iOS' && !clientData.device.toLowerCase().includes('simulator') @@ -181,6 +189,7 @@ export default class Server extends EventEmitter { |} = rawData; if (json.method === 'signCertificate') { console.debug('CSR received from device', 'server'); + const {csr, destination} = json; return new Single(subscriber => { subscriber.onSubscribe(); @@ -193,10 +202,15 @@ export default class Server extends EventEmitter { }), metadata: '', }); + this.emit('finish-client-setup', { + client, + deviceId: result.deviceId, + }); }) .catch(e => { console.error(e, 'server'); subscriber.onError(e); + this.emit('client-setup-error', {client, error: e}); }); }); }