Loading libs/binder/rust/Android.bp +17 −5 Original line number Diff line number Diff line Loading @@ -3,12 +3,24 @@ rust_library { crate_name: "binder", srcs: ["src/lib.rs"], shared_libs: [ "libbinder_ndk", "libutils", ], rustlibs: [ "liblibc", "libbinder_ndk_bindgen", "libbinder_ndk_sys", ], host_supported: true, } rust_library { name: "libbinder_ndk_sys", crate_name: "binder_ndk_sys", srcs: [ "sys/lib.rs", ":libbinder_ndk_bindgen", ], shared_libs: [ "libbinder_ndk", ], host_supported: true, } Loading @@ -16,8 +28,8 @@ rust_library { rust_bindgen { name: "libbinder_ndk_bindgen", crate_name: "binder_ndk_bindgen", wrapper_src: "BinderBindings.h", source_stem: "ndk_bindings", wrapper_src: "sys/BinderBindings.h", source_stem: "bindings", cflags: [ "-x c++", ], Loading Loading @@ -69,6 +81,6 @@ rust_test { ], rustlibs: [ "liblibc", "libbinder_ndk_bindgen", "libbinder_ndk_sys", ], } libs/binder/rust/src/error.rs +0 −8 Original line number Diff line number Diff line Loading @@ -43,14 +43,6 @@ pub fn status_result(status: status_t) -> Result<()> { } } // impl Display for StatusCode { // fn fmt(&self, f: &mut Formatter) -> FmtResult { // write!(f, "StatusCode::{:?}", self) // } // } // impl error::Error for StatusCode {} fn parse_status_code(code: i32) -> StatusCode { match code { e if e == StatusCode::OK as i32 => StatusCode::OK, Loading libs/binder/rust/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ mod error; mod native; mod state; use binder_ndk_bindgen as sys; use binder_ndk_sys as sys; pub mod parcel; Loading libs/binder/rust/src/parcel.rs +95 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ use crate::error::{status_result, Result, StatusCode}; use crate::proxy::SpIBinder; use crate::sys; use std::cell::RefCell; use std::convert::TryInto; use std::mem::ManuallyDrop; use std::ptr; Loading Loading @@ -117,6 +118,55 @@ impl Parcel { } } /// Perform a series of writes to the `Parcel`, prepended with the length /// (in bytes) of the written data. /// /// The length `0i32` will be written to the parcel first, followed by the /// writes performed by the callback. The initial length will then be /// updated to the length of all data written by the callback, plus the /// size of the length elemement itself (4 bytes). /// /// # Examples /// /// After the following call: /// /// ``` /// # use binder::{Binder, Interface, Parcel}; /// # let mut parcel = Parcel::Owned(std::ptr::null_mut()); /// parcel.sized_write(|subparcel| { /// subparcel.write(&1u32)?; /// subparcel.write(&2u32)?; /// subparcel.write(&3u32) /// }); /// ``` /// /// `parcel` will contain the following: /// /// ```ignore /// [16i32, 1u32, 2u32, 3u32] /// ``` pub fn sized_write<F>(&mut self, f: F) -> Result<()> where for<'a> F: Fn(&'a WritableSubParcel<'a>) -> Result<()> { let start = self.get_data_position(); self.write(&0i32)?; { let subparcel = WritableSubParcel(RefCell::new(self)); f(&subparcel)?; } let end = self.get_data_position(); unsafe { self.set_data_position(start)?; } assert!(end >= start); self.write(&(end - start))?; unsafe { self.set_data_position(end)?; } Ok(()) } /// Returns the current position in the parcel data. pub fn get_data_position(&self) -> i32 { unsafe { Loading @@ -143,6 +193,16 @@ impl Parcel { } } /// A segment of a writable parcel, used for [`Parcel::sized_write`]. pub struct WritableSubParcel<'a>(RefCell<&'a mut Parcel>); impl<'a> WritableSubParcel<'a> { /// Write a type that implements [`Serialize`] to the sub-parcel. pub fn write<S: Serialize + ?Sized>(&self, parcelable: &S) -> Result<()> { parcelable.serialize(&mut *self.0.borrow_mut()) } } // Data deserialization methods impl Parcel { /// Attempt to read a type that implements [`Deserialize`] from this Loading Loading @@ -445,3 +505,38 @@ fn test_utf8_utf16_conversions() { ); assert_eq!(parcel.read::<Vec<String>>().unwrap(), [s1, s2, s3]); } #[test] fn test_sized_write() { use crate::binder::Interface; use crate::native::Binder; let mut service = Binder::new(()).as_binder(); let mut parcel = Parcel::new_for_test(&mut service).unwrap(); let start = parcel.get_data_position(); let arr = [1i32, 2i32, 3i32]; parcel.sized_write(|subparcel| { subparcel.write(&arr[..]) }).expect("Could not perform sized write"); // i32 sub-parcel length + i32 array length + 3 i32 elements let expected_len = 20i32; assert_eq!(parcel.get_data_position(), start + expected_len); unsafe { parcel.set_data_position(start).unwrap(); } assert_eq!( expected_len, parcel.read().unwrap(), ); assert_eq!( parcel.read::<Vec<i32>>().unwrap(), &arr, ); } libs/binder/rust/src/proxy.rs +20 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,14 @@ impl AssociateClass for SpIBinder { } } impl PartialEq for SpIBinder { fn eq(&self, other: &Self) -> bool { ptr::eq(self.0, other.0) } } impl Eq for SpIBinder {} impl Clone for SpIBinder { fn clone(&self) -> Self { unsafe { Loading Loading @@ -363,6 +371,18 @@ impl WpIBinder { assert!(!ptr.is_null()); Self(ptr) } /// Promote this weak reference to a strong reference to the binder object. pub fn promote(&self) -> Option<SpIBinder> { unsafe { // Safety: `WpIBinder` always contains a valid weak reference, so we // can pass this pointer to `AIBinder_Weak_promote`. Returns either // null or an AIBinder owned by the caller, both of which are valid // to pass to `SpIBinder::from_raw`. let ptr = sys::AIBinder_Weak_promote(self.0); SpIBinder::from_raw(ptr) } } } /// Rust wrapper around DeathRecipient objects. Loading Loading
libs/binder/rust/Android.bp +17 −5 Original line number Diff line number Diff line Loading @@ -3,12 +3,24 @@ rust_library { crate_name: "binder", srcs: ["src/lib.rs"], shared_libs: [ "libbinder_ndk", "libutils", ], rustlibs: [ "liblibc", "libbinder_ndk_bindgen", "libbinder_ndk_sys", ], host_supported: true, } rust_library { name: "libbinder_ndk_sys", crate_name: "binder_ndk_sys", srcs: [ "sys/lib.rs", ":libbinder_ndk_bindgen", ], shared_libs: [ "libbinder_ndk", ], host_supported: true, } Loading @@ -16,8 +28,8 @@ rust_library { rust_bindgen { name: "libbinder_ndk_bindgen", crate_name: "binder_ndk_bindgen", wrapper_src: "BinderBindings.h", source_stem: "ndk_bindings", wrapper_src: "sys/BinderBindings.h", source_stem: "bindings", cflags: [ "-x c++", ], Loading Loading @@ -69,6 +81,6 @@ rust_test { ], rustlibs: [ "liblibc", "libbinder_ndk_bindgen", "libbinder_ndk_sys", ], }
libs/binder/rust/src/error.rs +0 −8 Original line number Diff line number Diff line Loading @@ -43,14 +43,6 @@ pub fn status_result(status: status_t) -> Result<()> { } } // impl Display for StatusCode { // fn fmt(&self, f: &mut Formatter) -> FmtResult { // write!(f, "StatusCode::{:?}", self) // } // } // impl error::Error for StatusCode {} fn parse_status_code(code: i32) -> StatusCode { match code { e if e == StatusCode::OK as i32 => StatusCode::OK, Loading
libs/binder/rust/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ mod error; mod native; mod state; use binder_ndk_bindgen as sys; use binder_ndk_sys as sys; pub mod parcel; Loading
libs/binder/rust/src/parcel.rs +95 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ use crate::error::{status_result, Result, StatusCode}; use crate::proxy::SpIBinder; use crate::sys; use std::cell::RefCell; use std::convert::TryInto; use std::mem::ManuallyDrop; use std::ptr; Loading Loading @@ -117,6 +118,55 @@ impl Parcel { } } /// Perform a series of writes to the `Parcel`, prepended with the length /// (in bytes) of the written data. /// /// The length `0i32` will be written to the parcel first, followed by the /// writes performed by the callback. The initial length will then be /// updated to the length of all data written by the callback, plus the /// size of the length elemement itself (4 bytes). /// /// # Examples /// /// After the following call: /// /// ``` /// # use binder::{Binder, Interface, Parcel}; /// # let mut parcel = Parcel::Owned(std::ptr::null_mut()); /// parcel.sized_write(|subparcel| { /// subparcel.write(&1u32)?; /// subparcel.write(&2u32)?; /// subparcel.write(&3u32) /// }); /// ``` /// /// `parcel` will contain the following: /// /// ```ignore /// [16i32, 1u32, 2u32, 3u32] /// ``` pub fn sized_write<F>(&mut self, f: F) -> Result<()> where for<'a> F: Fn(&'a WritableSubParcel<'a>) -> Result<()> { let start = self.get_data_position(); self.write(&0i32)?; { let subparcel = WritableSubParcel(RefCell::new(self)); f(&subparcel)?; } let end = self.get_data_position(); unsafe { self.set_data_position(start)?; } assert!(end >= start); self.write(&(end - start))?; unsafe { self.set_data_position(end)?; } Ok(()) } /// Returns the current position in the parcel data. pub fn get_data_position(&self) -> i32 { unsafe { Loading @@ -143,6 +193,16 @@ impl Parcel { } } /// A segment of a writable parcel, used for [`Parcel::sized_write`]. pub struct WritableSubParcel<'a>(RefCell<&'a mut Parcel>); impl<'a> WritableSubParcel<'a> { /// Write a type that implements [`Serialize`] to the sub-parcel. pub fn write<S: Serialize + ?Sized>(&self, parcelable: &S) -> Result<()> { parcelable.serialize(&mut *self.0.borrow_mut()) } } // Data deserialization methods impl Parcel { /// Attempt to read a type that implements [`Deserialize`] from this Loading Loading @@ -445,3 +505,38 @@ fn test_utf8_utf16_conversions() { ); assert_eq!(parcel.read::<Vec<String>>().unwrap(), [s1, s2, s3]); } #[test] fn test_sized_write() { use crate::binder::Interface; use crate::native::Binder; let mut service = Binder::new(()).as_binder(); let mut parcel = Parcel::new_for_test(&mut service).unwrap(); let start = parcel.get_data_position(); let arr = [1i32, 2i32, 3i32]; parcel.sized_write(|subparcel| { subparcel.write(&arr[..]) }).expect("Could not perform sized write"); // i32 sub-parcel length + i32 array length + 3 i32 elements let expected_len = 20i32; assert_eq!(parcel.get_data_position(), start + expected_len); unsafe { parcel.set_data_position(start).unwrap(); } assert_eq!( expected_len, parcel.read().unwrap(), ); assert_eq!( parcel.read::<Vec<i32>>().unwrap(), &arr, ); }
libs/binder/rust/src/proxy.rs +20 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,14 @@ impl AssociateClass for SpIBinder { } } impl PartialEq for SpIBinder { fn eq(&self, other: &Self) -> bool { ptr::eq(self.0, other.0) } } impl Eq for SpIBinder {} impl Clone for SpIBinder { fn clone(&self) -> Self { unsafe { Loading Loading @@ -363,6 +371,18 @@ impl WpIBinder { assert!(!ptr.is_null()); Self(ptr) } /// Promote this weak reference to a strong reference to the binder object. pub fn promote(&self) -> Option<SpIBinder> { unsafe { // Safety: `WpIBinder` always contains a valid weak reference, so we // can pass this pointer to `AIBinder_Weak_promote`. Returns either // null or an AIBinder owned by the caller, both of which are valid // to pass to `SpIBinder::from_raw`. let ptr = sys::AIBinder_Weak_promote(self.0); SpIBinder::from_raw(ptr) } } } /// Rust wrapper around DeathRecipient objects. Loading