-
-
Save 0tii/b5e5852b609ccf02414fd8075713caa8 to your computer and use it in GitHub Desktop.
Start an Android Virtual Device on Windows from a WSL shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable @typescript-eslint/no-var-requires */ | |
const exec = require('child_process').exec; | |
const spawn = require('child_process').spawn; | |
const readline = require('readline'); | |
// utility to add ansii escape codes to strings (external) | |
const { green, yellow, red } = require('./util/console-color'); | |
// utility to shallow-validate the android sdk path (external) | |
const { validateAndroidHomeWin } = require('./util/validate-android-home'); | |
/* | |
ANDROID_HOME_WIN points to the mounted Windows Android SDK path | |
e.g. /mnt/c/Users/<user>/AppData/Local/Android/Sdk | |
*/ | |
const RUN_CMD = `${process.env.ANDROID_HOME_WIN}/emulator/emulator`; | |
const LIST_CMD = `${process.env.ANDROID_HOME_WIN}/emulator/emulator -avd -list-avds`; | |
if (validateAndroidHomeWin(process.env.ANDROID_HOME_WIN, false)) | |
(async () => { | |
await runEmulator(); | |
})(); | |
function getDevices() { | |
return new Promise((resolve, reject) => { | |
exec(LIST_CMD, (error, stdout) => { | |
if (error) { | |
if (error.message.includes('emulator/emulator:')) { | |
console.error( | |
'Error retrieving device list, unpatched Sdk directory. Please run wsl-setup first.' // <-- .exe files have not been copied to their non-exe counterparts | |
); | |
} else { | |
console.error(`Error retrieving list of devices: ${error.message}`); | |
} | |
reject(error); | |
return; | |
} | |
const result = stdout; | |
const devices = result | |
.split('\n') | |
.map((name) => name.trim()) | |
.filter((name) => name); | |
resolve(devices); | |
}); | |
}); | |
} | |
async function runEmulator() { | |
const emulators = await getDevices(); | |
if (emulators.length === 0) { | |
console.log('No devices available.'); | |
return; | |
} | |
console.log('Select an emulator:\n'); | |
emulators.forEach((emulator, index) => { | |
console.log(` [${index + 1}] ${emulator}`); | |
}); | |
const selectedEmulatorIndex = await getUserInput('\nEmulator: '); | |
if (isValidIndex(selectedEmulatorIndex, emulators.length)) { | |
const selectedEmulator = emulators[selectedEmulatorIndex - 1]; | |
console.log(green(`\nStarting ${selectedEmulator}...`)); | |
try { | |
const emulatorProcess = spawn(RUN_CMD, ['-avd', selectedEmulator]); | |
emulatorProcess.on('close', (code) => { | |
if (code !== 0) | |
console.log(red(`${selectedEmulator} exited with error.`)); | |
else console.log(yellow(`${selectedEmulator} exited gracefully.`)); | |
}); | |
emulatorProcess.stderr.on('error', () => { | |
console.log( | |
red( | |
`${selectedEmulator} encountered an error and had to be shut down.` | |
) | |
); | |
}); | |
} catch (err) { | |
console.error('Error running emulator.'); | |
} | |
} else { | |
console.log('Invalid selection.'); | |
} | |
} | |
function getUserInput(prompt) { | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
return new Promise((resolve) => { | |
rl.question(prompt, (answer) => { | |
rl.close(); | |
resolve(answer.trim()); | |
}); | |
}); | |
} | |
function isValidIndex(index, arrayLength) { | |
return !isNaN(index) && index >= 1 && index <= arrayLength; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment