feat(dev): an Android failure looks exactly like a success
The APK installs and launches. It also dies six milliseconds later, and finding that out cost a cycle for three reasons that have nothing to do with the bug itself: **Go's stdout does not reach logcat.** An Android app's fd 1 and 2 go to /dev/null, so every slog line -- including the one naming the error the app is about to exit on -- is discarded. `setprop log.redirect-stdio true` does not help: that redirects the Java runtime's System.out, and our code is a c-shared native library. **os.Exit leaves no evidence.** No panic, no AndroidRuntime stack, nothing in /data/tombstones, nothing in `logcat -b crash` or dropbox. All three places anyone would look are empty, and the one signal that is present -- "Zygote: exited due to signal 9" -- reads as "the system killed it" and sends you after the low-memory killer. **ActivityManager restarts it faster than you can observe.** pidof always answers and `am start` always reports Status: ok, so a crash-looping app looks alive. "Did it start" is the wrong question; `make android-smoke` asks whether it is the *same pid* N seconds later, and prints the filtered logcat plus how to read it when it is not. The tell, once known: "I/WailsBridge: Wails bridge initialized" followed immediately by a new pid doing the same thing. scripts/android-emulator.sh follows dev-headless.sh's shape -- background start, saved-PID stop, filtered log tail, never pkill -f. Two scaffold tasks are deliberately not wrapped: `android:logs` greps logcat for (Wails|yellowjacket), which catches the WailsBridge tag but misses the app's own process tag (app.yellowjacket is lowercase) and misses ActivityManager's "has died" line, which is the one that says it crashed; and `ensure-emulator` boots whatever `-list-avds | tail -1` returns, with no pidfile and no boot wait, so it cannot be sequenced. One environment note that is not obvious on Arch: Gradle needs a platform and /opt/android-sdk has none, so ANDROID_SDK defaults to ~/Android/Sdk while ANDROID_NDK points at /opt/android-ndk. Two SDKs, one for each half of the build.
This commit is contained in:
@@ -38,6 +38,46 @@ dev-stop: ## Stop the headless app (SIGTERM, so shutdown hooks run)
|
||||
dev-logs: ## Tail the headless app log
|
||||
@tail -f .dev/app.log
|
||||
|
||||
# ---------------------------------------------------------------- #
|
||||
# The Android tier. See .pi/skills/yellowjacket-dev/references/ #
|
||||
# android-tier.md for which of these to reach for and why a failure #
|
||||
# here looks like nothing at all. #
|
||||
# ---------------------------------------------------------------- #
|
||||
|
||||
# The NDK is pinned: r26d is what the pipeline is built and checked
|
||||
# against, and newer NDKs have broken Wails' Android build before.
|
||||
# ANDROID_HOME must carry a *platform*, which Arch's /opt/android-sdk
|
||||
# does not — hence the separate default.
|
||||
ANDROID_SDK ?= $(HOME)/Android/Sdk
|
||||
ANDROID_NDK ?= /opt/android-ndk
|
||||
ANDROID_ENV := ANDROID_HOME=$(ANDROID_SDK) ANDROID_SDK_ROOT=$(ANDROID_SDK) ANDROID_NDK_HOME=$(ANDROID_NDK)
|
||||
|
||||
android: build-frontend ## Build the fat APK (arm64 + x86_64) into bin/
|
||||
@$(ANDROID_ENV) PATH="$(TOOLBIN):$$PATH" go tool wails3 task android:package:fat
|
||||
|
||||
android-setup: ## Install the SDK pieces and create the AVD (once, ~3.5GB)
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh setup
|
||||
|
||||
android-emulator: ## Boot the emulator headless in the background and wait for it
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh start
|
||||
|
||||
android-emulator-stop: ## Shut the emulator down (console kill, then saved PID)
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh stop
|
||||
|
||||
android-install: ## Install bin/yellowjacket.apk onto the running emulator
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh install
|
||||
|
||||
android-launch: ## Force-stop, clear logcat, and start the app
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh launch
|
||||
|
||||
android-logs: ## Tail logcat, filtered to the app's own tags
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh logs
|
||||
|
||||
# "Did it start" is the wrong question — a crash-looping app starts
|
||||
# several times a second. This asserts the *same pid* is still there.
|
||||
android-smoke: ## Launch and assert the app is still alive (SECONDS=<n>)
|
||||
@$(ANDROID_ENV) ./scripts/android-emulator.sh smoke $(if $(SECONDS),$(SECONDS),10)
|
||||
|
||||
# Seeds are produced by *running the app* — driving the real AddLibrary
|
||||
# binding and waiting for the real scan — never by hand-writing a
|
||||
# config.toml and DB rows. A hand-built seed is a second description
|
||||
|
||||
Reference in New Issue
Block a user