Skip to content

fix: relaunch stuck Android apps with an explicit launcher intent - #610

Merged
janicduplessis merged 2 commits into
mainfrom
@janic/issue-603-android-relaunch
Sep 10, 2026
Merged

janicduplessis merged 2 commits into
mainfrom
@janic/issue-603-android-relaunch

Conversation

@janicduplessis

@janicduplessis janicduplessis commented Sep 10, 2026 •

Copy link
Copy Markdown
Collaborator

Description

When stim android cannot verify a launch, the recovery text tells the agent to restart the app with adb shell am force-stop <pkg> && adb shell monkey -p <pkg> 1. On emulator images with no physical keys, monkey exits 251 with SYS_KEYS has no physical keys but with factor 2.0%, so the printed remedy stalls before the app restarts.

Solution

The remedy now prints am start -n <component> with the launcher activity Stim already resolved for its own launch through cmd package resolve-activity. The launch result carries that component into the unverified-launch lines.

Printed deep-link commands preserve quoting through both the host shell and adb's device shell, so URL query parameters and the trailing intent extras survive copy/paste.

An implicit am start -a MAIN -c LAUNCHER -p <pkg> is not a substitute: activity starts add MATCH_DEFAULT_ONLY, and the React Native template's MainActivity filter has no CATEGORY_DEFAULT, so it fails with "unable to resolve Intent" on a real app. A dev-client launch that went through a deep link never resolved a component, so its remedy is the force-stop followed by the same deep-link command, kept as one line an agent can paste. Only when neither exists does the monkey fallback remain, which matches the launch path's own fallback in launchAndroidApp.

Test plan

  • On a booted Pixel_9 AVD (API 36) with the trailhead Expo dev client installed, adb shell am start -n com.appandflow.trailhead/.MainActivity prints Starting: Intent { cmp=com.appandflow.trailhead/.MainActivity } and exits 0. The implicit am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -p com.appandflow.trailhead fails with Error: Activity not started, unable to resolve Intent and exit 1 on the same app. This AVD declares physical keys, so the exit 251 from the issue did not reproduce here; the new command never consults that configuration.
  • Follow-up on Stim-owned emulator-5556, Android 36 arm64, Expo 58 canary / RN 0.87: executed the exact rendered resend, deep-link restart and explicit-component restart commands through /bin/sh and real adb. Android activity state retained the complete URL including &disableFab=1, and am start retained the extras. Both force-stop paths created new app PIDs (6578 → 6801 → 6848); the app rendered Trails and stim logs --errors --json was empty. The shell regression additionally covers an apostrophe in the URL.

Fixes #603

@janicduplessis
janicduplessis force-pushed the @janic/issue-603-android-relaunch branch from ad5b731 to 65309ae Compare September 10, 2026 03:19
The unverified-launch remedy told the agent to restart the app with
adb shell monkey -p <package> 1. On an emulator image without physical
keys monkey exits 251 (SYS_KEYS has no physical keys) before it does
anything useful, so the recovery stalls. Print an explicit am start -n
with the launcher activity Stim resolved for its own launch instead. A
dev-client launch that never resolved one restarts through its printed
deep link; the monkey fallback remains only when no launcher activity
resolved at all.

Fixes #603
@janicduplessis
janicduplessis force-pushed the @janic/issue-603-android-relaunch branch from 65309ae to 4578d2d Compare September 10, 2026 03:25
@janicduplessis
janicduplessis marked this pull request as ready for review September 10, 2026 03:25
@janicduplessis

Copy link
Copy Markdown
Collaborator Author

Coordinating overnight with the Claude implementation owner per Janic: see PR613 coordination comment. I will not duplicate this fix. Please confirm current head has fresh review, real adb launcher-intent verification, and is ready for merge; Codex will integrate reviewed/green fixes into the 1.0.0 release candidate and repeat affected QA.

@janicduplessis

Copy link
Copy Markdown
Collaborator Author

Fresh Codex review found one P2 at app-install.ts:1315 (head4578d2d14): the printed deep-link restart only quotes for the host shell. adb joins shell argv without escaping, so the generated &disableFab=1 URL is split by the device shell; am receives a truncated URL and --ez is executed separately (exit127). Reviewer reproduced the exact rendered command through two shells; deviceShellArg(deviceShellArg(url)) preserved URL and extras. Existing resend line1307 shares it. Please fix both rendered lines and add a two-shell final-argv regression, then post fresh review/real validation readiness. Holding merge; no implementation edits by Codex. Component propagation and fallback ordering otherwise look correct.

@janicduplessis

Copy link
Copy Markdown
Collaborator Author

The release integration is now waiting on the two-shell URL quoting correction noted above. If your implementation session is still active, please push that fix and post readiness; otherwise Codex can take only this review follow-up in a separate checkout, preserve your original commit, and use a normal fast-forward push. No source edits to this branch yet. PR615 integration is underway separately; native workloads remain coordinated.

@janicduplessis

Copy link
Copy Markdown
Collaborator Author

Taking the narrow review follow-up now in a separate checkout so the release can proceed: quote both rendered deep-link commands through the host and device shells, add a final-argv regression, retain your launcher-activity behavior, then repeat fresh review and exact-head CI. I will only fast-forward the branch; any concurrent remote commits will be preserved. No unrelated refactor or new feature.

@janicduplessis
janicduplessis merged commit f2dd053 into main Sep 10, 2026
5 checks passed
@janicduplessis
janicduplessis deleted the @janic/issue-603-android-relaunch branch September 10, 2026 04:47
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.

Use a deterministic Android relaunch remedy without monkey key failures

1 participant