Add option to cold boot emulators

Summary: This is useful when your emulator freezes.

Reviewed By: mweststrate

Differential Revision: D25998579

fbshipit-source-id: 236c16c3008f0e33d62e4c486b5a04383b1a59ba
This commit is contained in:
John Knox
2021-01-25 08:55:03 -08:00
committed by Facebook GitHub Bot
parent d77940a839
commit 3e911c8288
3 changed files with 55 additions and 24 deletions

View File

@@ -202,16 +202,20 @@ export default class AndroidDevice extends BaseDevice {
}
}
export async function launchEmulator(name: string) {
export async function launchEmulator(name: string, coldBoot: boolean = false) {
// On Linux, you must run the emulator from the directory it's in because
// reasons ...
return which('emulator')
.then((emulatorPath) => {
if (emulatorPath) {
const child = spawn(emulatorPath, [`@${name}`], {
detached: true,
cwd: dirname(emulatorPath),
});
const child = spawn(
emulatorPath,
[`@${name}`, ...(coldBoot ? ['-no-snapshot-load'] : [])],
{
detached: true,
cwd: dirname(emulatorPath),
},
);
child.stderr.on('data', (data) => {
console.error(`Android emulator error: ${data}`);
});

View File

@@ -8,8 +8,13 @@
*/
import React, {useEffect, useState} from 'react';
import {Modal, Button, message, Alert} from 'antd';
import {AndroidOutlined, AppleOutlined} from '@ant-design/icons';
import {Modal, Button, message, Alert, Menu, Dropdown} from 'antd';
import {
AppleOutlined,
PoweroffOutlined,
MoreOutlined,
AndroidOutlined,
} from '@ant-design/icons';
import {Store} from '../../reducers';
import {useStore} from '../../utils/useStore';
import {launchEmulator} from '../../devices/AndroidDevice';
@@ -23,6 +28,8 @@ import {
import GK from '../../fb-stubs/GK';
import {JSEmulatorLauncherSheetSandy} from '../../chrome/JSEmulatorLauncherSheet';
const COLD_BOOT = 'cold-boot';
export function showEmulatorLauncher(store: Store) {
renderReactRoot((unmount) => (
<Provider store={store}>
@@ -65,25 +72,45 @@ export const LaunchEmulatorDialog = withTrackingScope(
}, [iosEnabled, getSimulators]);
const items = [
...androidEmulators.map((name) => (
<Button
key={name}
icon={<AndroidOutlined />}
onClick={() =>
launchEmulator(name)
.catch((e) => {
console.error(e);
message.error('Failed to start emulator: ' + e);
})
.then(onClose)
}>
{name}
</Button>
)),
...(androidEmulators.length > 0 ? [<AndroidOutlined />] : []),
...androidEmulators.map((name) => {
const launch = (coldBoot: boolean) => {
launchEmulator(name, coldBoot)
.catch((e) => {
console.error(e);
message.error('Failed to start emulator: ' + e);
})
.then(onClose);
};
const menu = (
<Menu
onClick={({key}) => {
switch (key) {
case COLD_BOOT: {
launch(true);
break;
}
}
}}>
<Menu.Item key={COLD_BOOT} icon={<PoweroffOutlined />}>
Cold Boot
</Menu.Item>
</Menu>
);
return (
<Dropdown.Button
key={name}
overlay={menu}
icon={<MoreOutlined />}
onClick={() => launch(false)}>
{name}
</Dropdown.Button>
);
}),
...(iosEmulators.length > 0 ? [<AppleOutlined />] : []),
...iosEmulators.map((device) => (
<Button
key={device.udid}
icon={<AppleOutlined />}
onClick={() =>
launchSimulator(device.udid)
.catch((e) => {

View File

@@ -66,5 +66,5 @@ test('Can render and launch android apps', async () => {
fireEvent.click(renderer.getByText('emulator2'));
await sleep(1000);
expect(onClose).toBeCalled();
expect(launchEmulator).toBeCalledWith('emulator2');
expect(launchEmulator).toBeCalledWith('emulator2', false);
});