Skip to content

Ensure AndroidAppWaker owns an ALooper reference#227

Merged
rib merged 1 commit intomainfrom
rib/pr/app-waker-acquire-release
Mar 3, 2026
Merged

Ensure AndroidAppWaker owns an ALooper reference#227
rib merged 1 commit intomainfrom
rib/pr/app-waker-acquire-release

Conversation

@rib
Copy link
Member

@rib rib commented Mar 3, 2026

This ensures we call ALooper_acquire before create_waker() wraps the Looper pointer with AndroidAppWaker and it also ensures that ::clone() and ::drop() call ALooper_acquire() and ALooper_release() respectively.

Contrary to what the comment for the looper member said previously, it was not safe to assume that the application's looper pointer had a 'static lifetime.

The looper pointer would only be valid up until android_main returns, but unlike a traditional main() function an android_main() runs with respect to an Activity lifecycle and not a process lifecycle.

It's technically possible for android_main() to return (at which point any looper stored in 'static storage would have previously become an invalid pointer) and then JNI could be used to re-enter Rust and potentially try and dereference that invalid pointer.

This adds a shared implementation of AndroidAppWaker to src/waker.rs instead of having each backend implement AndroidAppWaker.

Fixes: #226

This ensures we call `ALooper_acquire` before `create_waker()` wraps the
Looper pointer with `AndroidAppWaker` and it also ensures that
`::clone()` and `::drop()` call `ALooper_acquire()` and
`ALooper_release()` respectively.

Contrary to what the comment for the `looper` member said previously, it
was not safe to assume that the application's looper pointer had a
`'static` lifetime.

The looper pointer would only be valid up until `android_main` returns,
but unlike a traditional `main()` function an `android_main()` runs
with respect to an `Activity` lifecycle and not a process lifecycle.

It's technically possible for `android_main()` to return (at which point
any looper stored in `'static` storage would have previously become an
invalid pointer) and then JNI could be used to re-enter Rust and
potentially try and dereference that invalid pointer.

This adds a shared implementation of `AndroidAppWaker` to `src/waker.rs`
instead of having each backend implement `AndroidAppWaker`.

Fixes: #226
@rib rib force-pushed the rib/pr/app-waker-acquire-release branch from ede024f to 3d37cc0 Compare March 3, 2026 00:13
@rib rib merged commit 2b20da7 into main Mar 3, 2026
7 checks passed
@rib rib deleted the rib/pr/app-waker-acquire-release branch March 3, 2026 00:31
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.

AndroidAppWaker is not sound because AndroidApp/looper does not _actually_ have a 'static lifetime

1 participant