1import { CommandError } from '../../../utils/errors';
2import { Device, getAttachedDevicesAsync } from './adb';
3import { listAvdsAsync } from './emulator';
4
5/** Get a list of all devices including offline emulators. Asserts if no devices are available. */
6export async function getDevicesAsync(): Promise<Device[]> {
7  const bootedDevices = await getAttachedDevicesAsync();
8
9  const data = await listAvdsAsync();
10  const connectedNames = bootedDevices.map(({ name }) => name);
11
12  const offlineEmulators = data
13    .filter(({ name }) => !connectedNames.includes(name))
14    .map(({ name, type }) => {
15      return {
16        name,
17        type,
18        isBooted: false,
19        // TODO: Are emulators always authorized?
20        isAuthorized: true,
21      };
22    });
23
24  const allDevices = bootedDevices.concat(offlineEmulators);
25
26  if (!allDevices.length) {
27    throw new CommandError(
28      [
29        `No Android connected device found, and no emulators could be started automatically.`,
30        `Please connect a device or create an emulator (https://docs.expo.dev/workflow/android-studio-emulator).`,
31        `Then follow the instructions here to enable USB debugging:`,
32        `https://developer.android.com/studio/run/device.html#developer-device-options. If you are using Genymotion go to Settings -> ADB, select "Use custom Android SDK tools", and point it at your Android SDK directory.`,
33      ].join('\n')
34    );
35  }
36
37  return allDevices;
38}
39