diff --git a/apps/orchestrator/src/domains/command/executor.ts b/apps/orchestrator/src/domains/command/executor.ts index 0ef266c..457b3dc 100644 --- a/apps/orchestrator/src/domains/command/executor.ts +++ b/apps/orchestrator/src/domains/command/executor.ts @@ -22,17 +22,34 @@ export class AndroidCommandExecutor { ["-s", serial, "shell", "am", "force-stop", packageName], { allowFailure: true }, ); - await this.run([ - "-s", + const launchActivity = await this.resolveLauncherActivity( serial, - "shell", - "monkey", - "-p", packageName, - "-c", - "android.intent.category.LAUNCHER", - "1", - ]); + ); + + if (launchActivity) { + await this.run([ + "-s", + serial, + "shell", + "am", + "start", + "-n", + launchActivity, + ]); + } else { + await this.run([ + "-s", + serial, + "shell", + "monkey", + "-p", + packageName, + "-c", + "android.intent.category.LAUNCHER", + "1", + ]); + } return { serial }; } @@ -54,4 +71,41 @@ export class AndroidCommandExecutor { throw error; } } + + private async resolveLauncherActivity( + serial: string, + packageName: string, + ): Promise { + const result = await this.run( + [ + "-s", + serial, + "shell", + "cmd", + "package", + "resolve-activity", + "--brief", + "-a", + "android.intent.action.MAIN", + "-c", + "android.intent.category.LAUNCHER", + packageName, + ], + { allowFailure: true }, + ); + + const output = `${result.stdout ?? ""}\n${result.stderr ?? ""}`; + const lines = output + .split("\n") + .map((line) => line.trim()) + .filter(Boolean); + + for (const line of lines) { + if (line.includes("/") && !line.startsWith("priority=")) { + return line; + } + } + + return null; + } } diff --git a/memory.log.md b/memory.log.md index 322f9b2..2a9045c 100644 --- a/memory.log.md +++ b/memory.log.md @@ -102,3 +102,8 @@ Update rule: - Updated frontend session polling to use the new no-touch validity path and avoid stale query cache via forced refresh behavior. - Added frontend session end command to explicitly release the linked device on session teardown/ejection. - Updated admin link revoke flow to release the linked device after revocation so revoked sessions do not leave devices stuck `inUse`. + +### 15 — Orchestrator App Launch Robustness + +- Updated Android launch flow in orchestrator to resolve launcher activity via `cmd package resolve-activity` and launch with `am start -n `. +- Kept `monkey` as fallback only when launcher activity cannot be resolved, reducing redroid/device-specific `monkey` failures during session prepare.