Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions lib/emulator-manager.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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: {
Expand All @@ -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`);
Expand Down Expand Up @@ -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`, [], {
Expand All @@ -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++;
}
});
}
Expand Down
57 changes: 46 additions & 11 deletions src/emulator-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down Expand Up @@ -123,11 +120,53 @@ async function adb(port: number, command: string): Promise<number> {
* Wait for emulator to boot.
*/
async function waitForDevice(port: number, emulatorBootTimeout: number): Promise<void> {
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`, [], {
Expand All @@ -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++;
}
}

Expand Down
Loading