@@ -2,7 +2,7 @@ import { runCmd, whichCmd } from '../../utils/exec.ts';
22import type { ExecResult } from '../../utils/exec.ts' ;
33import { AppError , asAppError } from '../../utils/errors.ts' ;
44import type { DeviceInfo } from '../../utils/device.ts' ;
5- import { Deadline , retryWithPolicy , type RetryTelemetryEvent } from '../../utils/retry.ts' ;
5+ import { Deadline , retryWithPolicy , TIMEOUT_PROFILES , type RetryTelemetryEvent } from '../../utils/retry.ts' ;
66import { bootFailureHint , classifyBootFailure } from '../boot-diagnostics.ts' ;
77
88const EMULATOR_SERIAL_PREFIX = 'emulator-' ;
@@ -19,9 +19,13 @@ function isEmulatorSerial(serial: string): boolean {
1919 return serial . startsWith ( EMULATOR_SERIAL_PREFIX ) ;
2020}
2121
22- async function readAndroidBootProp ( serial : string ) : Promise < ExecResult > {
22+ async function readAndroidBootProp (
23+ serial : string ,
24+ timeoutMs = TIMEOUT_PROFILES . android_boot . operationMs ,
25+ ) : Promise < ExecResult > {
2326 return runCmd ( 'adb' , adbArgs ( serial , [ 'shell' , 'getprop' , 'sys.boot_completed' ] ) , {
2427 allowFailure : true ,
28+ timeoutMs,
2529 } ) ;
2630}
2731
@@ -30,6 +34,7 @@ async function resolveAndroidDeviceName(serial: string, rawModel: string): Promi
3034 if ( ! isEmulatorSerial ( serial ) ) return modelName || serial ;
3135 const avd = await runCmd ( 'adb' , adbArgs ( serial , [ 'emu' , 'avd' , 'name' ] ) , {
3236 allowFailure : true ,
37+ timeoutMs : TIMEOUT_PROFILES . android_boot . operationMs ,
3338 } ) ;
3439 const avdName = avd . stdout . trim ( ) ;
3540 if ( avd . exitCode === 0 && avdName ) {
@@ -44,7 +49,9 @@ export async function listAndroidDevices(): Promise<DeviceInfo[]> {
4449 throw new AppError ( 'TOOL_MISSING' , 'adb not found in PATH' ) ;
4550 }
4651
47- const result = await runCmd ( 'adb' , [ 'devices' , '-l' ] ) ;
52+ const result = await runCmd ( 'adb' , [ 'devices' , '-l' ] , {
53+ timeoutMs : TIMEOUT_PROFILES . android_boot . operationMs ,
54+ } ) ;
4855 const lines = result . stdout . split ( '\n' ) . map ( ( l : string ) => l . trim ( ) ) ;
4956 const entries = lines
5057 . filter ( ( line ) => line . length > 0 && ! line . startsWith ( 'List of devices' ) )
@@ -99,7 +106,11 @@ export async function waitForAndroidBoot(serial: string, timeoutMs = 60000): Pro
99106 message : 'timeout' ,
100107 } ) ;
101108 }
102- const result = await readAndroidBootProp ( serial ) ;
109+ const remainingMs = Math . max ( 1_000 , attemptDeadline ?. remainingMs ( ) ?? timeoutBudget ) ;
110+ const result = await readAndroidBootProp (
111+ serial ,
112+ Math . min ( remainingMs , TIMEOUT_PROFILES . android_boot . operationMs ) ,
113+ ) ;
103114 lastBootResult = result ;
104115 if ( result . stdout . trim ( ) === '1' ) return ;
105116 throw new AppError ( 'COMMAND_FAILED' , 'Android device is still booting' , {
0 commit comments