diff --git a/android-activity/src/game_activity/mod.rs b/android-activity/src/game_activity/mod.rs index c253274..6233335 100644 --- a/android-activity/src/game_activity/mod.rs +++ b/android-activity/src/game_activity/mod.rs @@ -174,19 +174,28 @@ impl AndroidApp { } } +// Wrapper around the raw android_app pointer that can be safely sent across threads. +// SAFETY: The android_app pointer is managed by the GameActivity glue code and protected +// by a Mutex. Access is synchronized and the pointer is cleared on APP_CMD_DESTROY. +// The Mutex wrapper provides Sync, so we only need to implement Send. +#[derive(Debug)] +struct SendAndroidApp(*mut ffi::android_app); + +unsafe impl Send for SendAndroidApp {} + #[derive(Debug, Clone)] struct GameActivityGlue { - game_activity_app: Arc>, + game_activity_app: Arc>, } impl GameActivityGlue { fn new(game_activity_app: *mut ffi::android_app) -> Self { Self { - game_activity_app: Arc::new(Mutex::new(game_activity_app)), + game_activity_app: Arc::new(Mutex::new(SendAndroidApp(game_activity_app))), } } - fn locked_app(&self) -> std::sync::MutexGuard<'_, *mut ffi::android_app> { + fn locked_app(&self) -> std::sync::MutexGuard<'_, SendAndroidApp> { self.game_activity_app.lock().unwrap() } @@ -203,7 +212,7 @@ impl GameActivityGlue { F: FnOnce(*mut ffi::android_app) -> R, { let app = self.locked_app(); - f(*app) + f(app.0) } /// Called when handling the `APP_CMD_DESTROY` event to clear our retained @@ -211,7 +220,7 @@ impl GameActivityGlue { /// accidentally access it after it's been freed. fn clear_app(&self) { let mut app = self.locked_app(); - *app = ptr::null_mut(); + app.0 = ptr::null_mut(); } } diff --git a/android-activity/src/init.rs b/android-activity/src/init.rs index 3995ee0..508e622 100644 --- a/android-activity/src/init.rs +++ b/android-activity/src/init.rs @@ -33,7 +33,7 @@ fn forward_stdio_to_logcat() -> std::thread::JoinHandle> { std::thread::Builder::new() .name("stdio-to-logcat".to_string()) .spawn(move || -> std::io::Result<()> { - let tag = CStr::from_bytes_with_nul(b"RustStdoutStderr\0").unwrap(); + let tag = c"RustStdoutStderr"; let mut reader = BufReader::new(file); let mut buffer = String::new(); loop { @@ -258,7 +258,7 @@ fn try_init_current_thread(env: &mut jni::Env, activity: &JObject) -> jni::error // Also name native thread - this needs to happen here after attaching to a JVM thread, // since that changes the thread name to something like "Thread-2". unsafe { - let thread_name = std::ffi::CStr::from_bytes_with_nul(b"android_main\0").unwrap(); + let thread_name = c"android_main"; let _ = libc::pthread_setname_np(libc::pthread_self(), thread_name.as_ptr()); } Ok(()) diff --git a/android-activity/src/input/sdk.rs b/android-activity/src/input/sdk.rs index dbe10f9..0bea028 100644 --- a/android-activity/src/input/sdk.rs +++ b/android-activity/src/input/sdk.rs @@ -78,9 +78,9 @@ jni::bind_java_type! { } impl AKeyCharacterMap<'_> { - pub(crate) fn get<'local>( + pub(crate) fn get( &self, - env: &'local mut jni::Env, + env: &mut jni::Env, key_code: jint, meta_state: jint, ) -> Result { @@ -97,10 +97,7 @@ impl AKeyCharacterMap<'_> { .map_err(|err| jni_utils::clear_and_map_exception_to_err(env, err)) } - pub(crate) fn get_keyboard_type<'local>( - &self, - env: &'local mut jni::Env, - ) -> Result { + pub(crate) fn get_keyboard_type(&self, env: &mut jni::Env) -> Result { self._get_keyboard_type(env) .map_err(|err| jni_utils::clear_and_map_exception_to_err(env, err)) } @@ -183,7 +180,7 @@ impl KeyCharacterMap { } }) .map_err(|err| { - let err: InternalAppError = err.into(); + let err: InternalAppError = err; err.into() }) } @@ -217,7 +214,7 @@ impl KeyCharacterMap { }) }) .map_err(|err| { - let err: InternalAppError = err.into(); + let err: InternalAppError = err; err.into() }) } @@ -239,7 +236,7 @@ impl KeyCharacterMap { Ok(keyboard_type.into()) }) .map_err(|err| { - let err: InternalAppError = err.into(); + let err: InternalAppError = err; err.into() }) } diff --git a/android-activity/src/lib.rs b/android-activity/src/lib.rs index 589454d..64fac0d 100644 --- a/android-activity/src/lib.rs +++ b/android-activity/src/lib.rs @@ -206,9 +206,9 @@ //! //! Before `android_main()` is called: //! - A `JavaVM` and -//! [`android.content.Context`](https://developer.android.com/reference/android/content/Context) -//! instance will be associated with the [`ndk_context`] crate so that other, -//! independent, Rust crates are able to find a JavaVM for making JNI calls. +//! [`android.content.Context`](https://developer.android.com/reference/android/content/Context) +//! instance will be associated with the [`ndk_context`] crate so that other, +//! independent, Rust crates are able to find a JavaVM for making JNI calls. //! - The `JavaVM` will be attached to the native thread (for JNI) //! - A [Looper] is attached to the Rust native thread. //! @@ -1358,7 +1358,7 @@ impl<'a> OnCreateState<'a> { /// - Don't wrap the reference in an `Auto` which would treat the reference /// like a local reference and try to delete it when dropped. pub fn activity_as_ptr(&self) -> *mut c_void { - self.java_activity as *mut c_void + self.java_activity } /// Returns the saved state of the `Activity` as a byte slice, which may be diff --git a/android-activity/src/native_activity/mod.rs b/android-activity/src/native_activity/mod.rs index 6ab89d5..5634f11 100644 --- a/android-activity/src/native_activity/mod.rs +++ b/android-activity/src/native_activity/mod.rs @@ -351,7 +351,7 @@ impl AndroidAppInner { return; } - let na_mut = na as *mut ndk_sys::ANativeActivity; + let na_mut = na; unsafe { ndk_sys::ANativeActivity_setWindowFlags( na_mut.cast(), diff --git a/android-activity/src/util.rs b/android-activity/src/util.rs index 6e04758..1345d4f 100644 --- a/android-activity/src/util.rs +++ b/android-activity/src/util.rs @@ -32,7 +32,7 @@ pub(crate) fn android_log(level: Level, tag: &CStr, msg: &CStr) { } pub(crate) fn log_panic(panic: Box) { - let rust_panic = unsafe { CStr::from_bytes_with_nul_unchecked(b"RustPanic\0") }; + let rust_panic = c"RustPanic"; if let Some(panic) = panic.downcast_ref::() { if let Ok(msg) = CString::new(panic.clone()) { @@ -43,10 +43,7 @@ pub(crate) fn log_panic(panic: Box) { android_log(Level::Error, rust_panic, &msg); } } else { - let unknown_panic = unsafe { CStr::from_bytes_with_nul_unchecked(b"UnknownPanic\0") }; - android_log(Level::Error, unknown_panic, unsafe { - CStr::from_bytes_with_nul_unchecked(b"\0") - }); + android_log(Level::Error, rust_panic, c"UnknownPanic"); } }