From 4705eb35d25a513c2b22fcd910fdcc765ad472e4 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 18 Mar 2024 15:13:09 +0100 Subject: [PATCH] Binder and parcel for `HardwareBuffer` --- ndk-sys/CHANGELOG.md | 1 + ndk-sys/Cargo.toml | 4 ++++ ndk-sys/src/lib.rs | 8 ++++++++ ndk-sys/wrapper.h | 2 ++ ndk/Cargo.toml | 5 ++++- ndk/src/hardware_buffer.rs | 30 ++++++++++++++++++++++++++++++ 6 files changed, 49 insertions(+), 1 deletion(-) diff --git a/ndk-sys/CHANGELOG.md b/ndk-sys/CHANGELOG.md index 4ff63c02..b1848503 100644 --- a/ndk-sys/CHANGELOG.md +++ b/ndk-sys/CHANGELOG.md @@ -4,6 +4,7 @@ - Generate against upstream NDK build `11769913`. (#471) - Add `nativewindow` feature to link against `libnativewindow`. (#465) +- Add `AIBinder` and `Parcel` # 0.5.0 (2023-10-15) diff --git a/ndk-sys/Cargo.toml b/ndk-sys/Cargo.toml index a17bae36..1b857f9e 100644 --- a/ndk-sys/Cargo.toml +++ b/ndk-sys/Cargo.toml @@ -15,10 +15,14 @@ categories = ["os", "os::android-apis", "external-ffi-bindings"] [dependencies] jni-sys = "0.3.0" +# Official crate from https://cs.android.com/android/platform/superproject/main/+/main:frameworks/native/libs/binder/rust/sys/ +android-binder-ndk-sys = { version = "0.1.0", optional = true } [features] test = [] + audio = [] +binder = ["android-binder-ndk-sys"] bitmap = [] media = [] nativewindow = [] diff --git a/ndk-sys/src/lib.rs b/ndk-sys/src/lib.rs index 14138af1..679b5304 100644 --- a/ndk-sys/src/lib.rs +++ b/ndk-sys/src/lib.rs @@ -45,6 +45,11 @@ extern "C" {} #[link(name = "mediandk")] extern "C" {} +// TODO: Delete. Taken care of in android-binder-ndk-sys +// #[cfg(all(feature = "binder", target_os = "android"))] +// #[link(name = "binder_ndk")] +// extern "C" {} + #[cfg(all(feature = "bitmap", target_os = "android"))] #[link(name = "jnigraphics")] extern "C" {} @@ -56,3 +61,6 @@ extern "C" {} #[cfg(all(feature = "sync", target_os = "android"))] #[link(name = "sync")] extern "C" {} + +#[cfg(all(feature = "binder", target_os = "android"))] +pub use android_binder_ndk_sys::*; diff --git a/ndk-sys/wrapper.h b/ndk-sys/wrapper.h index 670f2640..ee5b679f 100644 --- a/ndk-sys/wrapper.h +++ b/ndk-sys/wrapper.h @@ -1,6 +1,8 @@ #include #include #include +// XXX: Binder APIs are included/reexported/forwarded to official crate: +// https://cs.android.com/android/platform/superproject/main/+/main:frameworks/native/libs/binder/rust/sys/ // #include // #include // #include diff --git a/ndk/Cargo.toml b/ndk/Cargo.toml index 8378f6a0..0db66242 100644 --- a/ndk/Cargo.toml +++ b/ndk/Cargo.toml @@ -15,9 +15,10 @@ categories = ["os", "os::android-apis", "api-bindings"] [features] default = ["rwh_06"] -all = ["audio", "bitmap", "media", "nativewindow", "sync", "api-level-34", "rwh_04", "rwh_05", "rwh_06"] +all = ["audio", "binder", "bitmap", "media", "nativewindow", "sync", "api-level-34", "rwh_04", "rwh_05", "rwh_06"] audio = ["ffi/audio", "api-level-26"] +binder = ["ffi/binder", "dep:android-binder"] bitmap = ["ffi/bitmap"] media = ["ffi/media"] nativewindow = ["ffi/nativewindow"] @@ -47,6 +48,8 @@ rwh_04 = { package = "raw-window-handle", version = "0.4", optional = true } rwh_05 = { package = "raw-window-handle", version = "0.5", optional = true } rwh_06 = { package = "raw-window-handle", version = "0.6", optional = true } thiserror = "1.0.23" +# Official crate from https://cs.android.com/android/platform/superproject/main/+/main:frameworks/native/libs/binder/rust/ +android-binder = { version = "0.1.0", optional = true } [dependencies.jni] version = "0.21" diff --git a/ndk/src/hardware_buffer.rs b/ndk/src/hardware_buffer.rs index e5d4e3e3..0243310e 100644 --- a/ndk/src/hardware_buffer.rs +++ b/ndk/src/hardware_buffer.rs @@ -527,6 +527,36 @@ impl HardwareBuffer { HardwareBufferRef::from_ptr(self.inner) } } + + #[cfg(all(feature = "binder", feature = "api-level-34"))] + pub fn read_from_parcel( + parcel: android_binder::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result { + use android_binder::unstable_api::AsNative; + + let mut out = MaybeUninit::uninit(); + let status = + unsafe { ffi::AHardwareBuffer_readFromParcel(parcel.as_native(), out.as_mut_ptr()) }; + android_binder::unstable_api::status_result(status) + .and_then(|()| { + NonNull::new(unsafe { out.assume_init() }) + .ok_or(android_binder::StatusCode::UNEXPECTED_NULL) + }) + .map(|p| unsafe { HardwareBufferRef::from_ptr(p) }) + } + + #[cfg(all(feature = "binder", feature = "api-level-34"))] + pub fn write_to_parcel( + &self, + // TODO: mut parcel borrows? This API seems to allow writing either way. + mut parcel: android_binder::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<(), android_binder::StatusCode> { + use android_binder::unstable_api::AsNative; + + let status = + unsafe { ffi::AHardwareBuffer_writeToParcel(self.as_ptr(), parcel.as_native_mut()) }; + android_binder::unstable_api::status_result(status) + } } /// A [`HardwareBuffer`] with an owned reference, that is released when dropped.