/** * 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 React from 'react'; import {Store} from '../reducers/index'; import {Logger} from '../fb-interfaces/Logger'; import {FlipperServerImpl} from '../server/FlipperServerImpl'; import {selectClient, selectDevice} from '../reducers/connections'; import Client from '../Client'; import {notification} from 'antd'; import BaseDevice from '../devices/BaseDevice'; export default async (store: Store, logger: Logger) => { const {enableAndroid, androidHome, idbPath, enableIOS, enablePhysicalIOS} = store.getState().settingsState; const server = new FlipperServerImpl( { enableAndroid, androidHome, idbPath, enableIOS, enablePhysicalIOS, serverPorts: store.getState().application.serverPorts, }, store, logger, ); store.dispatch({ type: 'SET_FLIPPER_SERVER', payload: server, }); server.on('notification', (notif) => { notification.open({ message: notif.title, description: notif.description, type: notif.type, }); }); server.on('server-error', (err) => { notification.error({ message: 'Failed to start connection server', description: err.code === 'EADDRINUSE' ? ( <> Couldn't start connection server. Looks like you have multiple copies of Flipper running or another process is using the same port(s). As a result devices will not be able to connect to Flipper.

Please try to kill the offending process by running{' '} kill $(lsof -ti:PORTNUMBER) and restart flipper.

{'' + err} ) : ( <>Failed to start Flipper server: ${err.message} ), duration: null, }); }); server.on('device-connected', (deviceInfo) => { logger.track('usage', 'register-device', { os: deviceInfo.os, name: deviceInfo.title, serial: deviceInfo.serial, }); const device = new BaseDevice(server, deviceInfo); device.loadDevicePlugins( store.getState().plugins.devicePlugins, store.getState().connections.enabledDevicePlugins, ); store.dispatch({ type: 'REGISTER_DEVICE', payload: device, }); }); server.on('device-disconnected', (device) => { logger.track('usage', 'unregister-device', { os: device.os, serial: device.serial, }); // N.B.: note that we don't remove the device, we keep it in offline }); server.on('client-connected', (payload) => // TODO: fixed later in this stack handleClientConnected(store, payload as any), ); if (typeof window !== 'undefined') { window.addEventListener('beforeunload', () => { server.close(); }); } server .start() .then(() => { console.log( 'Flipper server started and accepting device / client connections', ); }) .catch((e) => { console.error('Failed to start Flipper server', e); notification.error({ message: 'Failed to start Flipper server', description: 'error: ' + e, }); }); return () => { server.close(); }; }; export async function handleClientConnected(store: Store, client: Client) { const {connections} = store.getState(); const existingClient = connections.clients.find((c) => c.id === client.id); if (existingClient) { existingClient.destroy(); store.dispatch({ type: 'CLEAR_CLIENT_PLUGINS_STATE', payload: { clientId: client.id, devicePlugins: new Set(), }, }); store.dispatch({ type: 'CLIENT_REMOVED', payload: client.id, }); } console.debug( `Device client initialized: ${client.id}. Supported plugins: ${Array.from( client.plugins, ).join(', ')}`, 'server', ); store.dispatch({ type: 'NEW_CLIENT', payload: client, }); // eslint-disable-next-line node/no-sync const device = client.deviceSync; if (device) { store.dispatch(selectDevice(device)); store.dispatch(selectClient(client.id)); } client.emit('plugins-change'); }