diff options
author | 2024-10-25 14:59:21 +0000 | |
---|---|---|
committer | 2024-10-25 14:59:21 +0000 | |
commit | dcca938df5392f77110c0a89820f0e22ae379b55 (patch) | |
tree | 04cc871aa32b209e6db826cf0ba2a54b2ea7a4ba | |
parent | f81814b5a2fcf8b0644630dfd5c445e4724d3971 (diff) | |
parent | 75d711270053226fea61534cac871d8967adb744 (diff) |
Merge changes Id4db842d,I58e41d34 into main
* changes:
rust: Bind to NDK subset of libbinder
rust: Make binder-ndk-sys crate buildable via Cargo for NDK
-rw-r--r-- | libs/binder/rust/Android.bp | 6 | ||||
-rw-r--r-- | libs/binder/rust/Cargo.toml | 15 | ||||
-rw-r--r-- | libs/binder/rust/build.rs | 4 | ||||
-rw-r--r-- | libs/binder/rust/src/binder.rs | 13 | ||||
-rw-r--r-- | libs/binder/rust/src/lib.rs | 24 | ||||
-rw-r--r-- | libs/binder/rust/src/native.rs | 33 | ||||
-rw-r--r-- | libs/binder/rust/src/parcel.rs | 2 | ||||
-rw-r--r-- | libs/binder/rust/src/proxy.rs | 2 | ||||
-rw-r--r-- | libs/binder/rust/src/service.rs | 1 | ||||
-rw-r--r-- | libs/binder/rust/sys/BinderBindings.hpp | 10 | ||||
-rw-r--r-- | libs/binder/rust/sys/Cargo.toml | 14 | ||||
-rw-r--r-- | libs/binder/rust/sys/build.rs | 59 | ||||
-rw-r--r-- | libs/binder/rust/sys/lib.rs | 1 |
13 files changed, 159 insertions, 25 deletions
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp index 020ebcce95..8404a48c26 100644 --- a/libs/binder/rust/Android.bp +++ b/libs/binder/rust/Android.bp @@ -139,6 +139,9 @@ rust_bindgen { "--raw-line", "use libc::sockaddr;", ], + cflags: [ + "-DANDROID_PLATFORM", + ], shared_libs: [ "libbinder_ndk", ], @@ -179,6 +182,9 @@ rust_bindgen { // rustified "libbinder_ndk_bindgen_flags.txt", ], + cflags: [ + "-DANDROID_PLATFORM", + ], shared_libs: [ "libbinder_ndk_on_trusty_mock", "libc++", diff --git a/libs/binder/rust/Cargo.toml b/libs/binder/rust/Cargo.toml new file mode 100644 index 0000000000..e5738c574a --- /dev/null +++ b/libs/binder/rust/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "android-binder" +version = "0.1.0" +edition = "2021" +description = "Safe bindings to Android Binder, restricted to the NDK" +license = "Apache-2.0" + +[dependencies] +binder-ndk-sys = { package = "android-binder-ndk-sys", version = "0.1", path = "./sys" } +downcast-rs = "1.2.1" +libc = "0.2.159" + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ["cfg(android_vendor)", "cfg(android_ndk)", "cfg(android_vndk)", "cfg(trusty)"] diff --git a/libs/binder/rust/build.rs b/libs/binder/rust/build.rs new file mode 100644 index 0000000000..f3e6b53778 --- /dev/null +++ b/libs/binder/rust/build.rs @@ -0,0 +1,4 @@ +fn main() { + // Anything with cargo is NDK only. If you want to access anything else, use Soong. + println!("cargo::rustc-cfg=android_ndk"); +} diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index 23026e593c..8c0501ba2f 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -207,8 +207,10 @@ pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION; /// Corresponds to TF_ONE_WAY -- an asynchronous call. pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY; /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made. +#[cfg(not(android_ndk))] pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF; /// Set to the vendor flag if we are building for the VNDK, 0 otherwise +#[cfg(not(android_ndk))] pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL; /// Internal interface of binder local or remote objects for making @@ -221,7 +223,7 @@ pub trait IBinderInternal: IBinder { fn is_binder_alive(&self) -> bool; /// Indicate that the service intends to receive caller security contexts. - #[cfg(not(android_vndk))] + #[cfg(not(any(android_vndk, android_ndk)))] fn set_requesting_sid(&mut self, enable: bool); /// Dump this object to the given file handle @@ -346,7 +348,6 @@ impl InterfaceClass { panic!("Expected non-null class pointer from AIBinder_Class_define!"); } sys::AIBinder_Class_setOnDump(class, Some(I::on_dump)); - sys::AIBinder_Class_setHandleShellCommand(class, None); class }; InterfaceClass(ptr) @@ -714,7 +715,7 @@ unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> { pub struct BinderFeatures { /// Indicates that the service intends to receive caller security contexts. This must be true /// for `ThreadState::with_calling_sid` to work. - #[cfg(not(android_vndk))] + #[cfg(not(any(android_vndk, android_ndk)))] pub set_requesting_sid: bool, // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct @@ -916,8 +917,12 @@ macro_rules! declare_binder_interface { impl $native { /// Create a new binder service. pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { + #[cfg(not(android_ndk))] let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability); - #[cfg(not(android_vndk))] + #[cfg(android_ndk)] + let mut binder = $crate::binder_impl::Binder::new($native(Box::new(inner))); + + #[cfg(not(any(android_vndk, android_ndk)))] $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); $crate::Strong::new(Box::new(binder)) } diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index f7f3f35c9f..14493db262 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -100,11 +100,11 @@ mod error; mod native; mod parcel; mod proxy; -#[cfg(not(trusty))] +#[cfg(not(any(trusty, android_ndk)))] mod service; -#[cfg(not(trusty))] +#[cfg(not(any(trusty, android_ndk)))] mod state; -#[cfg(not(any(android_vendor, android_vndk)))] +#[cfg(not(any(android_vendor, android_ndk, android_vndk)))] mod system_only; use binder_ndk_sys as sys; @@ -114,15 +114,18 @@ pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak}; pub use error::{ExceptionCode, IntoBinderResult, Status, StatusCode}; pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder}; pub use proxy::{DeathRecipient, SpIBinder, WpIBinder}; -#[cfg(not(trusty))] +#[cfg(not(any(trusty, android_ndk)))] pub use service::{ add_service, check_interface, check_service, force_lazy_services_persist, - get_declared_instances, get_interface, get_service, is_declared, is_handling_transaction, - register_lazy_service, wait_for_interface, wait_for_service, LazyServiceGuard, + get_declared_instances, is_declared, is_handling_transaction, register_lazy_service, + wait_for_interface, wait_for_service, LazyServiceGuard, }; -#[cfg(not(trusty))] +#[cfg(not(any(trusty, android_ndk)))] +#[allow(deprecated)] +pub use service::{get_interface, get_service}; +#[cfg(not(any(trusty, android_ndk)))] pub use state::{ProcessState, ThreadState}; -#[cfg(not(any(android_vendor, android_vndk)))] +#[cfg(not(any(android_vendor, android_vndk, android_ndk)))] pub use system_only::{delegate_accessor, Accessor, ConnectionInfo}; /// Binder result containing a [`Status`] on error. @@ -134,9 +137,10 @@ pub mod binder_impl { pub use crate::binder::{ IBinderInternal, InterfaceClass, LocalStabilityType, Remotable, Stability, StabilityType, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, VintfStabilityType, - FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, - LAST_CALL_TRANSACTION, + FIRST_CALL_TRANSACTION, FLAG_ONEWAY, LAST_CALL_TRANSACTION, }; + #[cfg(not(android_ndk))] + pub use crate::binder::{FLAG_CLEAR_BUF, FLAG_PRIVATE_LOCAL}; pub use crate::binder_async::BinderAsyncRuntime; pub use crate::error::status_t; pub use crate::native::Binder; diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs index c87cc94973..9e1cfd6b8f 100644 --- a/libs/binder/rust/src/native.rs +++ b/libs/binder/rust/src/native.rs @@ -14,9 +14,9 @@ * limitations under the License. */ -use crate::binder::{ - AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode, -}; +#[cfg(not(android_ndk))] +use crate::binder::Stability; +use crate::binder::{AsNative, Interface, InterfaceClassMethods, Remotable, TransactionCode}; use crate::error::{status_result, status_t, Result, StatusCode}; use crate::parcel::{BorrowedParcel, Serialize}; use crate::proxy::SpIBinder; @@ -76,14 +76,32 @@ impl<T: Remotable> Binder<T> { /// This moves the `rust_object` into an owned [`Box`] and Binder will /// manage its lifetime. pub fn new(rust_object: T) -> Binder<T> { - Self::new_with_stability(rust_object, Stability::default()) + #[cfg(not(android_ndk))] + { + Self::new_with_stability(rust_object, Stability::default()) + } + #[cfg(android_ndk)] + { + Self::new_unmarked(rust_object) + } } /// Create a new Binder remotable object with the given stability /// /// This moves the `rust_object` into an owned [`Box`] and Binder will /// manage its lifetime. + #[cfg(not(android_ndk))] pub fn new_with_stability(rust_object: T, stability: Stability) -> Binder<T> { + let mut binder = Self::new_unmarked(rust_object); + binder.mark_stability(stability); + binder + } + + /// Creates a new Binder remotable object with unset stability + /// + /// This is internal because normally we want to set the stability explicitly, + /// however for the NDK variant we cannot mark the stability. + fn new_unmarked(rust_object: T) -> Binder<T> { let class = T::get_class(); let rust_object = Box::into_raw(Box::new(rust_object)); // Safety: `AIBinder_new` expects a valid class pointer (which we @@ -93,9 +111,7 @@ impl<T: Remotable> Binder<T> { // decremented via `AIBinder_decStrong` when the reference lifetime // ends. let ibinder = unsafe { sys::AIBinder_new(class.into(), rust_object as *mut c_void) }; - let mut binder = Binder { ibinder, rust_object }; - binder.mark_stability(stability); - binder + Binder { ibinder, rust_object } } /// Set the extension of a binder interface. This allows a downstream @@ -189,6 +205,7 @@ impl<T: Remotable> Binder<T> { } /// Mark this binder object with the given stability guarantee + #[cfg(not(android_ndk))] fn mark_stability(&mut self, stability: Stability) { match stability { Stability::Local => self.mark_local_stability(), @@ -215,7 +232,7 @@ impl<T: Remotable> Binder<T> { /// Mark this binder object with local stability, which is vendor if we are /// building for android_vendor and system otherwise. - #[cfg(not(android_vendor))] + #[cfg(not(any(android_vendor, android_ndk)))] fn mark_local_stability(&mut self) { // Safety: Self always contains a valid `AIBinder` pointer, so we can // always call this C API safely. diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs index 3bfc425ee3..485b0bdb0d 100644 --- a/libs/binder/rust/src/parcel.rs +++ b/libs/binder/rust/src/parcel.rs @@ -197,6 +197,7 @@ unsafe impl<'a> AsNative<sys::AParcel> for BorrowedParcel<'a> { // Data serialization methods impl<'a> BorrowedParcel<'a> { /// Data written to parcelable is zero'd before being deleted or reallocated. + #[cfg(not(android_ndk))] pub fn mark_sensitive(&mut self) { // Safety: guaranteed to have a parcel object, and this method never fails unsafe { sys::AParcel_markSensitive(self.as_native()) } @@ -342,6 +343,7 @@ impl<'a> WritableSubParcel<'a> { impl Parcel { /// Data written to parcelable is zero'd before being deleted or reallocated. + #[cfg(not(android_ndk))] pub fn mark_sensitive(&mut self) { self.borrowed().mark_sensitive() } diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs index 04f1517556..593d12c1e9 100644 --- a/libs/binder/rust/src/proxy.rs +++ b/libs/binder/rust/src/proxy.rs @@ -298,7 +298,7 @@ impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { unsafe { sys::AIBinder_isAlive(self.as_native()) } } - #[cfg(not(android_vndk))] + #[cfg(not(any(android_vndk, android_ndk)))] fn set_requesting_sid(&mut self, enable: bool) { // Safety: `SpIBinder` guarantees that `self` always contains a valid // pointer to an `AIBinder`. diff --git a/libs/binder/rust/src/service.rs b/libs/binder/rust/src/service.rs index 29dd8e1f58..f4fdcf51c0 100644 --- a/libs/binder/rust/src/service.rs +++ b/libs/binder/rust/src/service.rs @@ -176,6 +176,7 @@ pub fn wait_for_service(name: &str) -> Option<SpIBinder> { /// seconds if it doesn't yet exist. #[deprecated = "this polls 5s, use wait_for_interface or check_interface"] pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> { + #[allow(deprecated)] interface_cast(get_service(name)) } diff --git a/libs/binder/rust/sys/BinderBindings.hpp b/libs/binder/rust/sys/BinderBindings.hpp index bd666fe0d7..557f0e895d 100644 --- a/libs/binder/rust/sys/BinderBindings.hpp +++ b/libs/binder/rust/sys/BinderBindings.hpp @@ -15,15 +15,19 @@ */ #include <android/binder_ibinder.h> +#include <android/binder_parcel.h> +#include <android/binder_status.h> + +/* Platform only */ +#if defined(ANDROID_PLATFORM) || defined(__ANDROID_VENDOR__) #include <android/binder_ibinder_platform.h> #include <android/binder_manager.h> -#include <android/binder_parcel.h> #include <android/binder_parcel_platform.h> #include <android/binder_process.h> #include <android/binder_rpc.h> #include <android/binder_shell.h> #include <android/binder_stability.h> -#include <android/binder_status.h> +#endif namespace android { @@ -81,8 +85,10 @@ enum { enum { FLAG_ONEWAY = FLAG_ONEWAY, +#if defined(ANDROID_PLATFORM) || defined(__ANDROID_VENDOR__) FLAG_CLEAR_BUF = FLAG_CLEAR_BUF, FLAG_PRIVATE_LOCAL = FLAG_PRIVATE_LOCAL, +#endif }; } // namespace consts diff --git a/libs/binder/rust/sys/Cargo.toml b/libs/binder/rust/sys/Cargo.toml new file mode 100644 index 0000000000..ad8e9c26f5 --- /dev/null +++ b/libs/binder/rust/sys/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "android-binder-ndk-sys" +version = "0.1.0" +edition = "2021" +description = "Bindgen bindings to android binder, restricted to the NDK" +license = "Apache-2.0" + +[dependencies] + +[lib] +path = "lib.rs" + +[build-dependencies] +bindgen = "0.70.1" diff --git a/libs/binder/rust/sys/build.rs b/libs/binder/rust/sys/build.rs new file mode 100644 index 0000000000..cb9c65ba51 --- /dev/null +++ b/libs/binder/rust/sys/build.rs @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use std::env; +use std::path::PathBuf; + +fn main() { + let ndk_home = PathBuf::from(env::var("ANDROID_NDK_HOME").unwrap()); + let toolchain = ndk_home.join("toolchains/llvm/prebuilt/linux-x86_64/"); + let sysroot = toolchain.join("sysroot"); + let bindings = bindgen::Builder::default() + .clang_arg(format!("--sysroot={}", sysroot.display())) + // TODO figure out what the "standard" #define is and use that instead + .header("BinderBindings.hpp") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + // Keep in sync with libbinder_ndk_bindgen_flags.txt + .default_enum_style(bindgen::EnumVariation::Rust { non_exhaustive: true }) + .constified_enum("android::c_interface::consts::.*") + .allowlist_type("android::c_interface::.*") + .allowlist_type("AStatus") + .allowlist_type("AIBinder_Class") + .allowlist_type("AIBinder") + .allowlist_type("AIBinder_Weak") + .allowlist_type("AIBinder_DeathRecipient") + .allowlist_type("AParcel") + .allowlist_type("binder_status_t") + .blocklist_function("vprintf") + .blocklist_function("strtold") + .blocklist_function("_vtlog") + .blocklist_function("vscanf") + .blocklist_function("vfprintf_worker") + .blocklist_function("vsprintf") + .blocklist_function("vsnprintf") + .blocklist_function("vsnprintf_filtered") + .blocklist_function("vfscanf") + .blocklist_function("vsscanf") + .blocklist_function("vdprintf") + .blocklist_function("vasprintf") + .blocklist_function("strtold_l") + .allowlist_function(".*") + .generate() + .expect("Couldn't generate bindings"); + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings."); + println!("cargo::rustc-link-lib=binder_ndk"); +} diff --git a/libs/binder/rust/sys/lib.rs b/libs/binder/rust/sys/lib.rs index 5352473272..349e5a9cc8 100644 --- a/libs/binder/rust/sys/lib.rs +++ b/libs/binder/rust/sys/lib.rs @@ -20,6 +20,7 @@ use std::error::Error; use std::fmt; #[cfg(not(target_os = "trusty"))] +#[allow(bad_style)] mod bindings { include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } |