Skip to content

Commit 7da4629

Browse files
Treehugger Robotandroid-build-merge-worker-robot
authored andcommitted
Merge "Add Accessor::from_binder" into main am: a222734
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/3362266 Change-Id: I692d08b3b2a320bdc9bb686008ea445e942105d8 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 parents 931a771 + a222734 commit 7da4629

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

libs/binder/rust/src/system_only.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,32 @@ impl Accessor {
9191
Accessor { accessor }
9292
}
9393

94+
/// Creates a new Accessor instance based on an existing Accessor's binder.
95+
/// This is useful when the Accessor instance is hosted in another process
96+
/// that has the permissions to create the socket connection FD.
97+
///
98+
/// The `instance` argument must match the instance that the original Accessor
99+
/// is responsible for.
100+
/// `instance` must not contain null bytes and is used to create a CString to
101+
/// pass through FFI.
102+
/// The `binder` argument must be a valid binder from an Accessor
103+
pub fn from_binder(instance: &str, binder: SpIBinder) -> Option<Accessor> {
104+
let inst = CString::new(instance).unwrap();
105+
106+
// Safety: All `SpIBinder` objects (the `binder` argument) hold a valid pointer
107+
// to an `AIBinder` that is guaranteed to remain valid for the lifetime of the
108+
// SpIBinder. `ABinderRpc_Accessor_fromBinder` creates a new pointer to that binder
109+
// that it is responsible for.
110+
// The `inst` argument is a new CString that will copied by
111+
// `ABinderRpc_Accessor_fromBinder` and not modified.
112+
let accessor =
113+
unsafe { sys::ABinderRpc_Accessor_fromBinder(inst.as_ptr(), binder.as_raw()) };
114+
if accessor.is_null() {
115+
return None;
116+
}
117+
Some(Accessor { accessor })
118+
}
119+
94120
/// Get the underlying binder for this Accessor for when it needs to be either
95121
/// registered with service manager or sent to another process.
96122
pub fn as_binder(&self) -> Option<SpIBinder> {

libs/binder/rust/tests/integration.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,34 @@ mod tests {
10381038
assert!(deleted.load(Ordering::Relaxed));
10391039
}
10401040

1041+
#[test]
1042+
fn test_accessor_from_accessor_binder() {
1043+
let get_connection_info = move |_instance: &str| None;
1044+
let accessor = Accessor::new("foo.service", get_connection_info);
1045+
let accessor2 =
1046+
Accessor::from_binder("foo.service", accessor.as_binder().unwrap()).unwrap();
1047+
assert_eq!(accessor.as_binder(), accessor2.as_binder());
1048+
}
1049+
1050+
#[test]
1051+
fn test_accessor_from_non_accessor_binder() {
1052+
let service_name = "rust_test_ibinder";
1053+
let _process = ScopedServiceProcess::new(service_name);
1054+
let binder = binder::get_service(service_name).unwrap();
1055+
assert!(binder.is_binder_alive());
1056+
1057+
let accessor = Accessor::from_binder("rust_test_ibinder", binder);
1058+
assert!(accessor.is_none());
1059+
}
1060+
1061+
#[test]
1062+
fn test_accessor_from_wrong_accessor_binder() {
1063+
let get_connection_info = move |_instance: &str| None;
1064+
let accessor = Accessor::new("foo.service", get_connection_info);
1065+
let accessor2 = Accessor::from_binder("NOT.foo.service", accessor.as_binder().unwrap());
1066+
assert!(accessor2.is_none());
1067+
}
1068+
10411069
#[tokio::test]
10421070
async fn reassociate_rust_binder_async() {
10431071
let service_name = "testing_service";

0 commit comments

Comments
 (0)