Skip to content

fix: wait for the input service before using it - #495

Open
soloturn wants to merge 1 commit into
ReactiveCircus:mainfrom
soloturn:fix/wait-for-input-service-and-settings-provider
Open

soloturn wants to merge 1 commit into
ReactiveCircus:mainfrom
soloturn:fix/wait-for-input-service-and-settings-provider

Conversation

@soloturn

@soloturn soloturn commented Sep 11, 2026 •

Copy link
Copy Markdown

AI-assisted change proposal. Filed by agent driven by @soloturn via GDD.

Fixes #432, duplicate of #489.

sys.boot_completed only means system_server reached its final boot phase - it doesn't guarantee every service has registered with ServiceManager by the time that property is externally observable over adb. input keyevent 82 right after boot can race InputManagerService's own registration:

java.lang.IllegalStateException: android.os.ServiceManager$ServiceNotFoundException: No service published for: input
	at android.hardware.input.InputManager.getInstance(InputManager.java:243)
	at com.android.commands.input.Input.injectKeyEvent(Input.java:355)

Independently reproduced with this exact stack trace in kiwix/kiwix-android#5047.

Fix

waitForService(port, 'input') polls adb shell service check input before the input keyevent 82 call, instead of assuming it's ready once waitForDevice() returns.

Test plan

  • npm run lint clean
  • npm run build (tsc) clean, lib/ regenerated
  • npm test - all 32 existing tests pass

@soloturn

Copy link
Copy Markdown
Author

@ychescale9 could you take a look at this when you have a chance?

Fixes ReactiveCircus#432, duplicate of ReactiveCircus#489.

sys.boot_completed only means system_server reached its final boot
phase - it doesn't guarantee every service has registered with
ServiceManager by the time that property is externally observable
over adb. `input keyevent 82` right after boot can race
InputManagerService's own registration and throw
ServiceNotFoundException: No service published for: input.

Adds waitForService(), polling `service check <name>` before the
input keyevent call.

Independently reproduced with the same stack trace in
kiwix/kiwix-android#5047.
@soloturn
soloturn force-pushed the fix/wait-for-input-service-and-settings-provider branch from ebfd7d9 to ab495a9 Compare September 11, 2026 11:45
@soloturn soloturn changed the title fix: wait for the input service and SettingsProvider before using them fix: wait for the input service before using it Sep 11, 2026
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite `steps:` can't loop over a `uses:` step, which
is why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop.
SDK installation and the initial AVD/snapshot stay exactly as before,
handled by the existing separate "Create AVD and generate snapshot for
caching" step upstream of this one - this only takes over AVD
creation + emulator launch + boot/input-service wait + test script +
teardown, since that's the part that needs retrying.

Preserves the two behaviors the old 3(4)-attempt version had:
attempt 1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite `steps:` can't loop over a `uses:` step, which
is why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop.
SDK installation and the initial AVD/snapshot stay exactly as before,
handled by the existing separate "Create AVD and generate snapshot for
caching" step upstream of this one - this only takes over AVD
creation + emulator launch + boot/input-service wait + test script +
teardown, since that's the part that needs retrying.

Preserves the two behaviors the old 3(4)-attempt version had:
attempt 1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 11, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Four more bugs found live, running this on a real matrix job:
- sdkmanager_bin/avdmanager_bin resolved via `find "$ANDROID_HOME"
  -maxdepth 4 -name ...`, which silently returned empty on one runner,
  turning "binary not found" into a cryptic "yes: Broken pipe" instead
  of a clear error. Both now use the fixed cmdline-tools path
  actions/runner-images actually uses, with an explicit check.
- `yes | sdkmanager --licenses` failed the whole step even when
  sdkmanager itself exited 0: composite shell: bash steps always run
  as `bash -e -o pipefail` regardless of this script's own `set` line,
  and once sdkmanager has nothing left to accept it closes stdin,
  giving `yes` a SIGPIPE that pipefail treats as a pipeline failure.
  Now `|| true`.
- Starting the emulator before any adb server exists races adb's
  device-registration handshake - observed going permanently
  "offline" and never recovering, so a getprop poll loop waits out the
  full timeout for a device that will never answer. Fixed two ways:
  `adb start-server` before the loop so the server is already up when
  the emulator registers, and swapping the blind getprop poll for
  `adb wait-for-device` (bounded to 60s) first - that blocks on adb's
  own transport-state tracking instead of repeatedly racing the daemon
  autostart with one-shot `adb shell` calls.
- `adb emu kill` alone can't guarantee the emulator actually dies: it
  needs a working adb connection, so on the offline-forever case above
  it silently no-ops (`2>/dev/null || true`) and leaves the process
  running - which then made every subsequent attempt in this same run
  fail instantly with "Running multiple emulators with the same AVD",
  while still burning the full boot-poll timeout before giving up.
  kill_emulator() now also kills the tracked PID directly and waits on
  it, regardless of adb connectivity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 12, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Four more bugs found live, running this on a real matrix job:
- sdkmanager_bin/avdmanager_bin resolved via `find "$ANDROID_HOME"
  -maxdepth 4 -name ...`, which silently returned empty on one runner,
  turning "binary not found" into a cryptic "yes: Broken pipe" instead
  of a clear error. Both now use the fixed cmdline-tools path
  actions/runner-images actually uses, with an explicit check.
- `yes | sdkmanager --licenses` failed the whole step even when
  sdkmanager itself exited 0: composite shell: bash steps always run
  as `bash -e -o pipefail` regardless of this script's own `set` line,
  and once sdkmanager has nothing left to accept it closes stdin,
  giving `yes` a SIGPIPE that pipefail treats as a pipeline failure.
  Now `|| true`.
- Starting the emulator before any adb server exists races adb's
  device-registration handshake - observed going permanently
  "offline" and never recovering, so a getprop poll loop waits out the
  full timeout for a device that will never answer. Fixed two ways:
  `adb start-server` before the loop so the server is already up when
  the emulator registers, and swapping the blind getprop poll for
  `adb wait-for-device` (bounded to 60s) first - that blocks on adb's
  own transport-state tracking instead of repeatedly racing the daemon
  autostart with one-shot `adb shell` calls.
- `adb emu kill` alone can't guarantee the emulator actually dies: it
  needs a working adb connection, so on the offline-forever case above
  it silently no-ops (`2>/dev/null || true`) and leaves the process
  running - which then made every subsequent attempt in this same run
  fail instantly with "Running multiple emulators with the same AVD",
  while still burning the full boot-poll timeout before giving up.
  kill_emulator() now also kills the tracked PID directly and waits on
  it, regardless of adb connectivity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 12, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Four more bugs found live, running this on a real matrix job:
- sdkmanager_bin/avdmanager_bin resolved via `find "$ANDROID_HOME"
  -maxdepth 4 -name ...`, which silently returned empty on one runner,
  turning "binary not found" into a cryptic "yes: Broken pipe" instead
  of a clear error. Both now use the fixed cmdline-tools path
  actions/runner-images actually uses, with an explicit check.
- `yes | sdkmanager --licenses` failed the whole step even when
  sdkmanager itself exited 0: composite shell: bash steps always run
  as `bash -e -o pipefail` regardless of this script's own `set` line,
  and once sdkmanager has nothing left to accept it closes stdin,
  giving `yes` a SIGPIPE that pipefail treats as a pipeline failure.
  Now `|| true`.
- Starting the emulator before any adb server exists races adb's
  device-registration handshake - observed going permanently
  "offline" and never recovering, so a getprop poll loop waits out the
  full timeout for a device that will never answer. Fixed two ways:
  `adb start-server` before the loop so the server is already up when
  the emulator registers, and swapping the blind getprop poll for
  `adb wait-for-device` (bounded to 60s) first - that blocks on adb's
  own transport-state tracking instead of repeatedly racing the daemon
  autostart with one-shot `adb shell` calls.
- `adb emu kill` alone can't guarantee the emulator actually dies: it
  needs a working adb connection, so on the offline-forever case above
  it silently no-ops (`2>/dev/null || true`) and leaves the process
  running - which then made every subsequent attempt in this same run
  fail instantly with "Running multiple emulators with the same AVD",
  while still burning the full boot-poll timeout before giving up.
  kill_emulator() now also kills the tracked PID directly and waits on
  it, regardless of adb connectivity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soloturn added a commit to soloturn/kiwix-android that referenced this pull request Sep 12, 2026
GitHub Actions composite steps can't loop over a uses: step, which is
why the previous version needed one hand-written YAML block per
attempt - going from 3 attempts to 4 meant copy-pasting a whole new
block, and it would again for 5, 6, etc. while waiting for
ReactiveCircus/android-emulator-runner#495 to ship.

Replaces that with a single script step wrapping a real bash loop. SDK
installation and the initial AVD/snapshot stay handled by the existing
separate 'Create AVD and generate snapshot for caching' step upstream
of this one on a cache miss; on a cache hit that step (and the SDK
install it triggers) is skipped entirely, so this step also has to:
- default ANDROID_AVD_HOME itself (only exported by that step's SDK
  install)
- install avdmanager/emulator/the system image itself before using
  them (same reason - reactivecircus/android-emulator-runner normally
  does this on every run regardless of AVD cache state; every other
  direct use of it elsewhere in this workflow still does)

Both caught live watching this run on a real cache-hit path, not in
review.

Preserves the two behaviors the old 3(4)-attempt version had: attempt
1 reuses the cached AVD/snapshot (-no-snapshot-save, no forced
recreation) exactly like before; only retries force a fresh AVD and a
genuinely cold boot (-no-snapshot), so a retry isn't just re-hitting
whatever state the first attempt already failed against.

Four more bugs found live, running this on a real matrix job:
- sdkmanager_bin/avdmanager_bin resolved via `find "$ANDROID_HOME"
  -maxdepth 4 -name ...`, which silently returned empty on one runner,
  turning "binary not found" into a cryptic "yes: Broken pipe" instead
  of a clear error. Both now use the fixed cmdline-tools path
  actions/runner-images actually uses, with an explicit check.
- `yes | sdkmanager --licenses` failed the whole step even when
  sdkmanager itself exited 0: composite shell: bash steps always run
  as `bash -e -o pipefail` regardless of this script's own `set` line,
  and once sdkmanager has nothing left to accept it closes stdin,
  giving `yes` a SIGPIPE that pipefail treats as a pipeline failure.
  Now `|| true`.
- Starting the emulator before any adb server exists races adb's
  device-registration handshake - observed going permanently
  "offline" and never recovering, so a getprop poll loop waits out the
  full timeout for a device that will never answer. Fixed two ways:
  `adb start-server` before the loop so the server is already up when
  the emulator registers, and swapping the blind getprop poll for
  `adb wait-for-device` (bounded to 60s) first - that blocks on adb's
  own transport-state tracking instead of repeatedly racing the daemon
  autostart with one-shot `adb shell` calls.
- `adb emu kill` alone can't guarantee the emulator actually dies: it
  needs a working adb connection, so on the offline-forever case above
  it silently no-ops (`2>/dev/null || true`) and leaves the process
  running - which then made every subsequent attempt in this same run
  fail instantly with "Running multiple emulators with the same AVD",
  while still burning the full boot-poll timeout before giving up.
  kill_emulator() now also kills the tracked PID directly and waits on
  it, regardless of adb connectivity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cmd: Can't find service: input

1 participant