@@ -356,22 +356,51 @@ def _spawn_emulator(cmd: list[str]) -> subprocess.Popen:
356356 env = env
357357 )
358358
359- # Try launch with explicit sdk-root first.
360- process = _spawn_emulator ([emulator_path , "-avd" , avd_name , "-sdk-root" , str (sdk_root )])
361- await asyncio .sleep (3 )
362- returncode = process .poll ()
359+ async def _attempt_launch (cmd : list [str ], wait_seconds : int , attempt_label : str ) -> tuple [subprocess .Popen , int | None ]:
360+ process = _spawn_emulator (cmd )
361+ await asyncio .sleep (wait_seconds )
362+ returncode = process .poll ()
363+ if returncode is not None and debug :
364+ launch_hint = _read_file_tail (log_path )
365+ print (
366+ f"[installer][emulator] Launch attempt '{ attempt_label } ' exited (code { returncode } ) "
367+ f"after { wait_seconds } s. Hint: { launch_hint [:300 ]} "
368+ )
369+ return process , returncode
370+
371+ # On macOS, emulator can fail a few seconds later on first-ever launch.
372+ probe_seconds = 12 if _is_darwin () else 3
363373
364- # macOS compatibility: retry without -sdk-root if first launch exits immediately.
374+ # Attempt 1: explicit sdk-root
375+ process , returncode = await _attempt_launch (
376+ [emulator_path , "-avd" , avd_name , "-sdk-root" , str (sdk_root )],
377+ probe_seconds ,
378+ "with-sdk-root" ,
379+ )
380+
381+ # Attempt 2 (macOS): fallback without -sdk-root
365382 if returncode is not None and _is_darwin ():
366383 if debug :
367- print ("[installer][emulator] Emulator exited quickly with -sdk-root on macOS. Retrying without -sdk-root." )
368- process = _spawn_emulator ([emulator_path , "-avd" , avd_name ])
369- await asyncio .sleep (3 )
370- returncode = process .poll ()
384+ print ("[installer][emulator] Retrying launch without -sdk-root on macOS." )
385+ process , returncode = await _attempt_launch (
386+ [emulator_path , "-avd" , avd_name ],
387+ probe_seconds ,
388+ "without-sdk-root" ,
389+ )
390+
391+ # Attempt 3 (macOS): disable snapshot loading on initial cold launch edge-cases
392+ if returncode is not None and _is_darwin ():
393+ if debug :
394+ print ("[installer][emulator] Retrying launch with -no-snapshot-load on macOS." )
395+ process , returncode = await _attempt_launch (
396+ [emulator_path , "-avd" , avd_name , "-no-snapshot-load" ],
397+ probe_seconds ,
398+ "no-snapshot-load" ,
399+ )
371400
372401 if returncode is not None :
373402 launch_hint = _read_file_tail (log_path )
374- error_msg = f"Emulator process for { avd_name } exited immediately (code { returncode } )."
403+ error_msg = f"Emulator process for { avd_name } exited during startup (code { returncode } )."
375404 if launch_hint :
376405 error_msg += f" Output hint: { launch_hint [:500 ]} "
377406 print (f"[installer][emulator] { error_msg } " )
0 commit comments