/**
* 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 ServerController from '../server/comms/ServerController';
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger';
import Client from '../Client';
import {UninitializedClient} from '../UninitializedClient';
import {addErrorNotification} from '../reducers/notifications';
import {CertificateExchangeMedium} from '../server/utils/CertificateProvider';
import {selectClient, selectDevice} from '../reducers/connections';
import {isLoggedIn} from '../fb-stubs/user';
import React from 'react';
import {notification, Typography} from 'antd';
import {ACTIVE_SHEET_SIGN_IN, setActiveSheet} from '../reducers/application';
export default (store: Store, logger: Logger) => {
const server = new ServerController(logger, store);
server.init();
server.addListener('new-client', (client: Client) => {
registerNewClient(store, client);
});
server.addListener('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 connection server: ${err.message}>
),
duration: null,
});
});
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',
({client, error}: {client: UninitializedClient; error: Error}) => {
store.dispatch(
addErrorNotification(
`Connection to '${client.appName}' on '${client.deviceName}' failed`,
'Failed to start client connection',
error,
),
);
},
);
server.addListener(
'client-unresponsive-error',
({
client,
medium,
}: {
client: UninitializedClient;
medium: CertificateExchangeMedium;
deviceID: string;
}) => {
store.dispatch(
addErrorNotification(
`Timed out establishing connection with "${client.appName}" on "${client.deviceName}".`,
medium === 'WWW' ? (
<>
Verify that both your computer and mobile device are on
Lighthouse/VPN{' '}
{!isLoggedIn().get() && (
<>
and{' '}
store.dispatch(setActiveSheet(ACTIVE_SHEET_SIGN_IN))
}>
log in to Facebook Intern
>
)}{' '}
so they can exchange certificates.{' '}
Check this link
{' '}
on how to enable VPN on mobile device.
>
) : (
'Verify that your client is connected to Flipper and that there is no error related to idb.'
),
),
);
},
);
if (typeof window !== 'undefined') {
window.addEventListener('beforeunload', () => {
server.close();
});
}
return server.close;
};
export function registerNewClient(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,
});
}
store.dispatch({
type: 'NEW_CLIENT',
payload: client,
});
const device = client.deviceSync;
if (device) {
store.dispatch(selectDevice(device));
store.dispatch(selectClient(client.id));
}
}