Skip to content

release-android: workaround wry getId() ProGuard regression (#8)#11

Merged
oscarvalenzuelab merged 1 commit into
mainfrom
fix/wry-getid-android-workaround
May 5, 2026
Merged

release-android: workaround wry getId() ProGuard regression (#8)#11
oscarvalenzuelab merged 1 commit into
mainfrom
fix/wry-getid-android-workaround

Conversation

@oscarvalenzuelab
Copy link
Copy Markdown
Owner

Closes #8.

Summary

Workaround in `release-android.yml` for the wry ProGuard regression
that crashes the Android APK at first launch with `tao 0.35` panicking
in `onActivityCreate`. Verified end-to-end on a Pixel 6 / Android 14
emulator: the patched APK launches into the chat shell.

Background: codex-validated investigation in
issue #8.
Upstream fix is tauri-apps/wry#1721
— merged today, awaiting a wry release. This workflow change goes away
the moment that release flows in transitively (the patch step is
idempotent and emits a `::notice::` if it sees the upstream fix already
in place).

What the new step does

Inserted between `Build APK` and `Sign APKs`:

  1. Find `proguard-wry.pro` under `src-tauri/gen/android`
  2. Idempotently patch the `WryActivity` keep block to add `int getId();`
  3. Wipe R8 + dex output dirs (Gradle's R8 task doesn't track the
    proguard file as an input, so we have to bust the cache)
  4. Re-run `./gradlew :app:assembleUniversalRelease` with `-x` on the
    four rust-build tasks (`.so`s are already built; running them via
    gradle standalone fails because they invoke `cargo tauri` which
    needs a parent WebSocket)
  5. Sanity-check via `dexdump` that `WryActivity.getId()` actually
    landed in the dex (scoped to the WryActivity class block — a
    false-positive on the unrelated `RustWebView.getId` would otherwise
    pass).

Codex review chain

  • Pre-PR: 3 findings, all addressed (unscoped dex grep, optional
    sanity check, find/pipefail)
  • Re-pass: 1 new finding caught (dexdump's class descriptor lines have
    leading whitespace → class-end anchor was wrong → in_block leaked
    past WryActivity)
  • Final pass: CLEAN

Test plan

  • Push a `desktop-v*` tag → release-android leg runs all the way
    through, produces a debug-signed universal APK
  • APK installs via `adb install` without
    `INSTALL_PARSE_FAILED_NO_CERTIFICATES`
  • APK launches on emulator into the chat shell (no
    `onActivityCreate` panic)
  • If wry releases the upstream fix mid-PR-cycle: the workflow
    emits `::notice::` and exits the patch path early, build still
    succeeds

`wry <= 0.55.0` ships a `proguard-wry.pro` template that's missing
`int getId();` from the WryActivity keep block. R8 strips the Kotlin
auto-generated getter (no Java/Kotlin code calls it), then tao 0.35's
JNI bridge calls `activity.getId()` at onActivityCreate, gets a
NoSuchMethodError, panics, and the APK crashes before its first
frame.

Upstream fix: tauri-apps/wry#1721 (merged 2026-05-04, awaiting
release). This workaround stays in place until the next wry release
flows in transitively, then this whole step gets deleted.

The workaround has to deal with two sharp edges:

  1. `cargo tauri android build --apk` regenerates `proguard-wry.pro`
     from wry's bundled template every run, so we can only patch it
     between init and the next R8 invocation.

  2. Gradle's R8 task does not declare the proguard file as an input,
     so editing it in place doesn't invalidate R8's incremental cache.
     We have to wipe R8 outputs to force a re-run.

Sequence: build → patch (idempotent, errors if the regex doesn't
match the current wry template) → wipe R8/dex outputs → re-run
gradle's `:app:assembleUniversalRelease` excluding the rust-build
tasks (the `.so`s are already built; running rust tasks via gradle
standalone fails because they invoke `cargo tauri` which needs a
parent WebSocket). Final dex sanity-check confirms the patched
`getId()` actually landed inside the WryActivity class block.

Codex review surfaced four findings, all addressed:
- [P1] Original dex grep matched any `getId` in the dex (RustWebView
  also has one), so a stripped WryActivity.getId could pass.
  Now scoped via awk to the WryActivity class block.
- [P1] Sanity check used to silently skip if APK or dexdump was
  missing. Both are now hard errors.
- [P1] dexdump emits class descriptor lines with leading spaces, so
  the awk's class-end anchor `^Class descriptor` never matched and
  in_block stayed true past WryActivity. Anchor now uses
  `^[[:space:]]*Class descriptor`.
- [P3] `find ... | head -n1` under pipefail risks SIGPIPE; switched
  to `find ... -print -quit` with an explicit search-root guard.
@oscarvalenzuelab oscarvalenzuelab merged commit 7192d20 into main May 5, 2026
2 checks passed
@oscarvalenzuelab oscarvalenzuelab deleted the fix/wry-getid-android-workaround branch May 5, 2026 07:00
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.

Android: tao 0.35 panics with JavaException in onActivityCreate (post HOME-fix)

1 participant