Sdk path should be used when launching emulator

Summary:
Changelog: Fixed issue where a missing ANDROID_SDK_ROOT env var made it impossible to launch emulators

Run into an issue where ANDROID_SDK_ROOT wasn't set for my user, causing Flipper not to be able to launch emulator, which was looked up from the path rather than using the flipper settings.

Fixes: https://github.com/facebook/flipper/issues/3119

Reviewed By: timur-valiev

Differential Revision: D33158280

fbshipit-source-id: ea5616b10265ed43f1012c58da081be275ff1d5b
This commit is contained in:
Michel Weststrate
2021-12-16 14:49:46 -08:00
committed by Facebook GitHub Bot
parent 730d47932d
commit ef2a86e7a8
4 changed files with 37 additions and 50 deletions

View File

@@ -204,6 +204,7 @@ function setProcessState(settings: Settings) {
if (!process.env.ANDROID_HOME && !process.env.ANDROID_SDK_ROOT) {
process.env.ANDROID_HOME = androidHome;
process.env.ANDROID_SDK_ROOT = androidHome;
}
// emulator/emulator is more reliable than tools/emulator, so prefer it if

View File

@@ -337,7 +337,7 @@ export class FlipperServerImpl implements FlipperServer {
},
'android-get-emulators': async () => this.android.getAndroidEmulators(),
'android-launch-emulator': async (name, coldBoot) =>
launchEmulator(name, coldBoot),
launchEmulator(this.config.settings.androidHome, name, coldBoot),
'ios-get-simulators': async (bootedOnly) =>
this.ios.getSimulators(bootedOnly),
'ios-launch-simulator': async (udid) => launchSimulator(udid),

View File

@@ -276,34 +276,32 @@ export default class AndroidDevice extends ServerDevice {
}
}
export async function launchEmulator(name: string, coldBoot: boolean = false) {
export async function launchEmulator(
androidHome: string,
name: string,
coldBoot: boolean = false,
) {
try {
// On Linux, you must run the emulator from the directory it's in because
// reasons ...
return which('emulator')
.catch(() =>
join(
process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT || '',
'emulator',
'emulator',
),
)
.then((emulatorPath) => {
if (emulatorPath) {
const emulatorPath = join(androidHome, 'emulator', 'emulator');
const child = spawn(
emulatorPath,
[`@${name}`, ...(coldBoot ? ['-no-snapshot-load'] : [])],
{
detached: true,
cwd: dirname(emulatorPath),
env: {
...process.env,
ANDROID_SDK_ROOT: androidHome,
},
},
);
child.stderr.on('data', (data) => {
console.warn(`Android emulator stderr: ${data}`);
});
child.on('error', (e) => console.warn('Android emulator error:', e));
} else {
throw new Error('Could not get emulator path');
} catch (e) {
console.warn('Android emulator startup failed:', e);
}
})
.catch((e) => console.error('Android emulator startup failed:', e));
}

View File

@@ -23,9 +23,6 @@ import {
} from '../../FlipperServerConfig';
export class AndroidDeviceManager {
// cache emulator path
private emulatorPath: string | undefined;
constructor(public flipperServer: FlipperServerImpl) {}
private createDevice(
@@ -119,25 +116,16 @@ export class AndroidDeviceManager {
});
}
async getEmulatorPath(): Promise<string> {
if (this.emulatorPath) {
return this.emulatorPath;
}
// TODO: this doesn't respect the currently configured android_home in settings!
try {
this.emulatorPath = (await promisify(which)('emulator')) as string;
} catch (_e) {
this.emulatorPath = join(
process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT || '',
getEmulatorPath(): string {
return join(
this.flipperServer.config.settings.androidHome,
'emulator',
'emulator',
);
}
return this.emulatorPath;
}
async getAndroidEmulators(): Promise<string[]> {
const emulatorPath = await this.getEmulatorPath();
const emulatorPath = this.getEmulatorPath();
return new Promise<string[]>((resolve) => {
child_process.execFile(
emulatorPath as string,