diff --git a/android-activity/CHANGELOG.md b/android-activity/CHANGELOG.md index 6124643..ca4be1f 100644 --- a/android-activity/CHANGELOG.md +++ b/android-activity/CHANGELOG.md @@ -3,8 +3,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + + +## [0.4.2] - 2022-02-16 ### Changed - The `Activity.finish()` method is now called when `android_main` returns so the `Activity` will be destroyed ([#67](https://github.com/rust-mobile/android-activity/issues/67)) +- The `native-activity` backend now propagates `NativeWindow` redraw/resize and `ContentRectChanged` callbacks to main loop ([#70](https://github.com/rust-mobile/android-activity/pull/70)) +- The `game-activity` implementation of `pointer_index()` was fixed to not always return `0` ([#80](https://github.com/rust-mobile/android-activity/pull/84)) +- Added `panic` guards around application's `android_main()` and native code that could potentially unwind across a Java FFI boundary ([#68](https://github.com/rust-mobile/android-activity/pull/68)) ## [0.4.1] - 2022-02-16 ### Added diff --git a/android-activity/Cargo.toml b/android-activity/Cargo.toml index db3f4ff..ed6a1b0 100644 --- a/android-activity/Cargo.toml +++ b/android-activity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "android-activity" -version = "0.4.1" +version = "0.4.2" edition = "2021" keywords = ["android", "ndk"] readme = "../README.md" diff --git a/examples/agdk-mainloop/Cargo.toml b/examples/agdk-mainloop/Cargo.toml index 47d30a3..6971468 100644 --- a/examples/agdk-mainloop/Cargo.toml +++ b/examples/agdk-mainloop/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" log = "0.4" android_logger = "0.11.0" android-activity = { path="../../android-activity", features = ["game-activity"] } +ndk-sys = "0.4" +ndk = "0.7" [lib] name="main" diff --git a/examples/agdk-mainloop/app/build.gradle b/examples/agdk-mainloop/app/build.gradle index 77c1a85..cce660e 100644 --- a/examples/agdk-mainloop/app/build.gradle +++ b/examples/agdk-mainloop/app/build.gradle @@ -3,6 +3,7 @@ plugins { } android { + ndkVersion "25.2.9519653" compileSdk 31 defaultConfig { @@ -32,6 +33,7 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + namespace 'co.realfit.agdkmainloop' } dependencies { diff --git a/examples/agdk-mainloop/app/src/main/AndroidManifest.xml b/examples/agdk-mainloop/app/src/main/AndroidManifest.xml index 7b99a0b..b9d7563 100644 --- a/examples/agdk-mainloop/app/src/main/AndroidManifest.xml +++ b/examples/agdk-mainloop/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + = Default::default(); + let mut native_window: Option = None; while !quit { app.poll_events( @@ -37,11 +37,11 @@ fn android_main(app: AndroidApp) { } } MainEvent::InitWindow { .. } => { - render_state = Some(()); + native_window = app.native_window(); redraw_pending = true; } MainEvent::TerminateWindow { .. } => { - render_state = None; + native_window = None; } MainEvent::WindowResized { .. } => { redraw_pending = true; @@ -65,7 +65,7 @@ fn android_main(app: AndroidApp) { } if redraw_pending { - if let Some(_rs) = render_state { + if let Some(native_window) = &native_window { redraw_pending = false; // Handle input @@ -75,9 +75,32 @@ fn android_main(app: AndroidApp) { }); info!("Render..."); + dummy_render(native_window); } } }, ); } } + +/// Post a NOP frame to the window +/// +/// Since this is a bare minimum test app we don't depend +/// on any GPU graphics APIs but we do need to at least +/// convince Android that we're drawing something and are +/// responsive, otherwise it will stop delivering input +/// events to us. +fn dummy_render(native_window: &ndk::native_window::NativeWindow) { + unsafe { + let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed(); + let mut rect: ndk_sys::ARect = std::mem::zeroed(); + ndk_sys::ANativeWindow_lock( + native_window.ptr().as_ptr() as _, + &mut buf as _, + &mut rect as _, + ); + // Note: we don't try and touch the buffer since that + // also requires us to handle various buffer formats + ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _); + } +} diff --git a/examples/na-mainloop/Cargo.toml b/examples/na-mainloop/Cargo.toml index 6280913..93da1d9 100644 --- a/examples/na-mainloop/Cargo.toml +++ b/examples/na-mainloop/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" log = "0.4" android_logger = "0.11.0" android-activity = { path="../../android-activity", features = [ "native-activity" ] } +ndk-sys = "0.4" +ndk = "0.7" [lib] #name="na_mainloop" diff --git a/examples/na-mainloop/app/build.gradle b/examples/na-mainloop/app/build.gradle index c17a5d3..dd102cc 100644 --- a/examples/na-mainloop/app/build.gradle +++ b/examples/na-mainloop/app/build.gradle @@ -3,6 +3,7 @@ plugins { } android { + ndkVersion "25.2.9519653" compileSdk 31 defaultConfig { @@ -32,6 +33,7 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + namespace 'co.realfit.namainloop' } dependencies { diff --git a/examples/na-mainloop/app/src/main/AndroidManifest.xml b/examples/na-mainloop/app/src/main/AndroidManifest.xml index 56fe639..d104641 100644 --- a/examples/na-mainloop/app/src/main/AndroidManifest.xml +++ b/examples/na-mainloop/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + = Default::default(); + let mut native_window: Option = None; while !quit { app.poll_events( @@ -37,11 +37,11 @@ fn android_main(app: AndroidApp) { } } MainEvent::InitWindow { .. } => { - render_state = Some(()); + native_window = app.native_window(); redraw_pending = true; } MainEvent::TerminateWindow { .. } => { - render_state = None; + native_window = None; } MainEvent::WindowResized { .. } => { redraw_pending = true; @@ -65,7 +65,7 @@ fn android_main(app: AndroidApp) { } if redraw_pending { - if let Some(_rs) = render_state { + if let Some(native_window) = &native_window { redraw_pending = false; // Handle input @@ -75,9 +75,32 @@ fn android_main(app: AndroidApp) { }); info!("Render..."); + dummy_render(native_window); } } }, ); } } + +/// Post a NOP frame to the window +/// +/// Since this is a bare minimum test app we don't depend +/// on any GPU graphics APIs but we do need to at least +/// convince Android that we're drawing something and are +/// responsive, otherwise it will stop delivering input +/// events to us. +fn dummy_render(native_window: &ndk::native_window::NativeWindow) { + unsafe { + let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed(); + let mut rect: ndk_sys::ARect = std::mem::zeroed(); + ndk_sys::ANativeWindow_lock( + native_window.ptr().as_ptr() as _, + &mut buf as _, + &mut rect as _, + ); + // Note: we don't try and touch the buffer since that + // also requires us to handle various buffer formats + ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _); + } +}