diff --git a/lib/emulator-manager.js b/lib/emulator-manager.js index 71c5c374e..2dad8bc5f 100644 --- a/lib/emulator-manager.js +++ b/lib/emulator-manager.js @@ -1,18 +1,18 @@ "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { +var __createBinding = (this && this.__createBinding) || (Object.create ? (function (o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; + desc = { enumerable: true, get: function () { return m[k]; } }; } Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { +}) : (function (o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function (o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { +}) : function (o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { @@ -72,6 +72,7 @@ function launchEmulator(systemImageApiLevel, target, arch, profile, cores, ramSi } // start emulator console.log('Starting emulator.'); + // Add a small delay to ensure emulator process starts properly yield exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -port ${port} -avd "${avdName}" ${emulatorOptions} &"`, [], { listeners: { @@ -82,8 +83,6 @@ function launchEmulator(systemImageApiLevel, target, arch, profile, cores, ramSi }, }, }); - // Wait a few seconds for emulator process to initialize before polling - yield delay(5000); // wait for emulator to complete booting yield waitForDevice(port, emulatorBootTimeout); yield adb(port, `shell input keyevent 82`); @@ -134,11 +133,47 @@ function adb(port, command) { */ function waitForDevice(port, emulatorBootTimeout) { return __awaiter(this, void 0, void 0, function* () { - let booted = false; - let attempts = 0; + const startTime = Date.now(); const retryInterval = 2; // retry every 2 seconds - const maxAttempts = emulatorBootTimeout / 2; + // Step 1: Poll until device appears in ADB + console.log('Waiting for emulator device to connect...'); + let deviceConnected = false; + while (!deviceConnected) { + const elapsedSeconds = (Date.now() - startTime) / 1000; + console.log('Attempting to connect at ' + elapsedSeconds + ' seconds' ); + if (elapsedSeconds > emulatorBootTimeout) { + throw new Error('Timeout waiting for emulator device to connect.'); + } + try { + // Try to get device state - will fail if device doesn't exist + let state = ''; + yield exec.exec(`adb -s emulator-${port} get-state`, [], { + listeners: { + stdout: (data) => { + state += data.toString(); + }, + }, + }); + if (state.trim() === 'device') { + deviceConnected = true; + } + } + catch (error) { + // Device not found yet, keep waiting + console.warn(error instanceof Error ? error.message : error); + } + if (!deviceConnected) { + yield delay(retryInterval * 1000); + } + } + console.log('Device connected. Waiting for boot to complete...'); + // Step 2: Poll for boot completion + let booted = false; while (!booted) { + const elapsedSeconds = (Date.now() - startTime) / 1000; + if (elapsedSeconds > emulatorBootTimeout) { + throw new Error('Timeout waiting for emulator to boot.'); + } try { let result = ''; yield exec.exec(`adb -s emulator-${port} shell getprop sys.boot_completed`, [], { @@ -151,19 +186,14 @@ function waitForDevice(port, emulatorBootTimeout) { if (result.trim() === '1') { console.log('Emulator booted.'); booted = true; - break; } } catch (error) { console.warn(error instanceof Error ? error.message : error); } - if (attempts < maxAttempts) { + if (!booted) { yield delay(retryInterval * 1000); } - else { - throw new Error(`Timeout waiting for emulator to boot.`); - } - attempts++; } }); } diff --git a/src/emulator-manager.ts b/src/emulator-manager.ts index 958ebc040..ae16f54fc 100644 --- a/src/emulator-manager.ts +++ b/src/emulator-manager.ts @@ -77,9 +77,6 @@ export async function launchEmulator( }, }); - // Wait a few seconds for emulator process to initialize before polling - await delay(5000); - // wait for emulator to complete booting await waitForDevice(port, emulatorBootTimeout); await adb(port, `shell input keyevent 82`); @@ -123,11 +120,53 @@ async function adb(port: number, command: string): Promise { * Wait for emulator to boot. */ async function waitForDevice(port: number, emulatorBootTimeout: number): Promise { - let booted = false; - let attempts = 0; + const startTime = Date.now(); const retryInterval = 2; // retry every 2 seconds - const maxAttempts = emulatorBootTimeout / 2; + + // Step 1: Poll until device appears in ADB + console.log('Waiting for emulator device to connect...'); + let deviceConnected = false; + + while (!deviceConnected) { + const elapsedSeconds = (Date.now() - startTime) / 1000; + if (elapsedSeconds > emulatorBootTimeout) { + throw new Error('Timeout waiting for emulator device to connect.'); + } + + try { + // Try to get device state - will fail if device doesn't exist + let state = ''; + await exec.exec(`adb -s emulator-${port} get-state`, [], { + listeners: { + stdout: (data: Buffer) => { + state += data.toString(); + }, + }, + }); + if (state.trim() === 'device') { + deviceConnected = true; + } + } catch (error) { + // Device not found yet, keep waiting + console.warn(error instanceof Error ? error.message : error); + } + + if (!deviceConnected) { + await delay(retryInterval * 1000); + } + } + + console.log('Device connected. Waiting for boot to complete...'); + + // Step 2: Poll for boot completion + let booted = false; + while (!booted) { + const elapsedSeconds = (Date.now() - startTime) / 1000; + if (elapsedSeconds > emulatorBootTimeout) { + throw new Error('Timeout waiting for emulator to boot.'); + } + try { let result = ''; await exec.exec(`adb -s emulator-${port} shell getprop sys.boot_completed`, [], { @@ -140,18 +179,14 @@ async function waitForDevice(port: number, emulatorBootTimeout: number): Promise if (result.trim() === '1') { console.log('Emulator booted.'); booted = true; - break; } } catch (error) { console.warn(error instanceof Error ? error.message : error); } - if (attempts < maxAttempts) { + if (!booted) { await delay(retryInterval * 1000); - } else { - throw new Error(`Timeout waiting for emulator to boot.`); } - attempts++; } }