blob: 036f6b4f01c639801b65998573087dff0d144813 [file] [log] [blame]
Stephen Crane2a3c2502020-06-16 17:48:35 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Rust API for interacting with a remote binder service.
18
19use crate::binder::{
Andrew Walbran12400d82021-03-04 17:04:34 +000020 AsNative, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Strong,
21 TransactionCode, TransactionFlags,
Stephen Crane2a3c2502020-06-16 17:48:35 -070022};
23use crate::error::{status_result, Result, StatusCode};
24use crate::parcel::{
Matthew Maurere268a9f2022-07-26 09:31:30 -070025 BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize,
26 SerializeArray, SerializeOption,
Stephen Crane2a3c2502020-06-16 17:48:35 -070027};
28use crate::sys;
29
Stephen Craneddb3e6d2020-12-18 13:27:22 -080030use std::cmp::Ordering;
Andrew Walbran12400d82021-03-04 17:04:34 +000031use std::convert::TryInto;
Stephen Crane098bbc92022-02-14 13:31:53 -080032use std::ffi::{c_void, CStr, CString};
Andrei Homescu2e3c1472020-08-11 16:35:40 -070033use std::fmt;
Alice Ryhlea9d9d22021-08-27 07:51:30 +000034use std::mem;
Stephen Crane098bbc92022-02-14 13:31:53 -080035use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070036use std::os::unix::io::AsRawFd;
37use std::ptr;
Alice Ryhlea9d9d22021-08-27 07:51:30 +000038use std::sync::Arc;
Stephen Crane2a3c2502020-06-16 17:48:35 -070039
40/// A strong reference to a Binder remote object.
41///
42/// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
43/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000044pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
Stephen Crane2a3c2502020-06-16 17:48:35 -070045
Andrei Homescu2e3c1472020-08-11 16:35:40 -070046impl fmt::Debug for SpIBinder {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.pad("SpIBinder")
49 }
50}
51
Stephen Crane2a3c2502020-06-16 17:48:35 -070052/// # Safety
53///
Stephen Cranef03fe3d2021-06-25 15:05:00 -070054/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
Stephen Crane2a3c2502020-06-16 17:48:35 -070055unsafe impl Send for SpIBinder {}
56
Stephen Cranef03fe3d2021-06-25 15:05:00 -070057/// # Safety
58///
59/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
60unsafe impl Sync for SpIBinder {}
61
Stephen Crane2a3c2502020-06-16 17:48:35 -070062impl SpIBinder {
63 /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
64 ///
65 /// # Safety
66 ///
67 /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
68 /// to an `AIBinder`.
69 ///
70 /// In the non-null case, this method conceptually takes ownership of a strong
71 /// reference to the object, so `AIBinder_incStrong` must have been called
72 /// on the pointer before passing it to this constructor. This is generally
73 /// done by Binder NDK methods that return an `AIBinder`, but care should be
74 /// taken to ensure this invariant.
75 ///
76 /// All `SpIBinder` objects that are constructed will hold a valid pointer
77 /// to an `AIBinder`, which will remain valid for the entire lifetime of the
78 /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
79 pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000080 ptr::NonNull::new(ptr).map(Self)
Stephen Crane2a3c2502020-06-16 17:48:35 -070081 }
82
Stephen Craned58bce02020-07-07 12:26:02 -070083 /// Extract a raw `AIBinder` pointer from this wrapper.
84 ///
85 /// This method should _only_ be used for testing. Do not try to use the NDK
86 /// interface directly for anything else.
87 ///
88 /// # Safety
89 ///
90 /// The resulting pointer is valid only as long as the SpIBinder is alive.
91 /// The SpIBinder object retains ownership of the AIBinder and the caller
92 /// should not attempt to free the returned pointer.
93 pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000094 self.0.as_ptr()
Stephen Craned58bce02020-07-07 12:26:02 -070095 }
96
Stephen Crane2a3c2502020-06-16 17:48:35 -070097 /// Return true if this binder object is hosted in a different process than
98 /// the current one.
99 pub fn is_remote(&self) -> bool {
100 unsafe {
101 // Safety: `SpIBinder` guarantees that it always contains a valid
102 // `AIBinder` pointer.
103 sys::AIBinder_isRemote(self.as_native())
104 }
105 }
106
107 /// Try to convert this Binder object into a trait object for the given
108 /// Binder interface.
109 ///
110 /// If this object does not implement the expected interface, the error
111 /// `StatusCode::BAD_TYPE` is returned.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800112 pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700113 FromIBinder::try_from(self)
114 }
115
116 /// Return the interface class of this binder object, if associated with
117 /// one.
Stephen Crane669deb62020-09-10 17:31:39 -0700118 pub fn get_class(&mut self) -> Option<InterfaceClass> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700119 unsafe {
120 // Safety: `SpIBinder` guarantees that it always contains a valid
121 // `AIBinder` pointer. `AIBinder_getClass` returns either a null
122 // pointer or a valid pointer to an `AIBinder_Class`. After mapping
123 // null to None, we can safely construct an `InterfaceClass` if the
124 // pointer was non-null.
125 let class = sys::AIBinder_getClass(self.as_native_mut());
126 class.as_ref().map(|p| InterfaceClass::from_ptr(p))
127 }
128 }
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000129
130 /// Creates a new weak reference to this binder object.
131 pub fn downgrade(&mut self) -> WpIBinder {
132 WpIBinder::new(self)
133 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700134}
135
Andrew Walbranff136e02022-08-02 17:16:12 +0000136fn interface_cast<T: FromIBinder + ?Sized>(service: Option<SpIBinder>) -> Result<Strong<T>> {
137 if let Some(service) = service {
138 FromIBinder::try_from(service)
139 } else {
140 Err(StatusCode::NAME_NOT_FOUND)
141 }
142}
143
Victor Hsiehd35d31d2021-06-03 11:24:31 -0700144pub mod unstable_api {
145 use super::{sys, SpIBinder};
146
147 /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
148 /// needed to bridge RPC binder, which doesn't have Rust API yet.
149 /// TODO(b/184872979): remove once the Rust API is created.
150 ///
151 /// # Safety
152 ///
153 /// See `SpIBinder::from_raw`.
154 pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
155 SpIBinder::from_raw(ptr)
156 }
157}
158
Stephen Crane2a3c2502020-06-16 17:48:35 -0700159/// An object that can be associate with an [`InterfaceClass`].
160pub trait AssociateClass {
161 /// Check if this object is a valid object for the given interface class
162 /// `I`.
163 ///
164 /// Returns `Some(self)` if this is a valid instance of the interface, and
165 /// `None` otherwise.
166 ///
167 /// Classes constructed by `InterfaceClass` are unique per type, so
168 /// repeatedly calling this method for the same `InterfaceClass` is allowed.
169 fn associate_class(&mut self, class: InterfaceClass) -> bool;
170}
171
172impl AssociateClass for SpIBinder {
173 fn associate_class(&mut self, class: InterfaceClass) -> bool {
174 unsafe {
175 // Safety: `SpIBinder` guarantees that it always contains a valid
176 // `AIBinder` pointer. An `InterfaceClass` can always be converted
177 // into a valid `AIBinder_Class` pointer, so these parameters are
178 // always safe.
179 sys::AIBinder_associateClass(self.as_native_mut(), class.into())
180 }
181 }
182}
183
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800184impl Ord for SpIBinder {
185 fn cmp(&self, other: &Self) -> Ordering {
186 let less_than = unsafe {
187 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
188 // this pointer is always safe to pass to `AIBinder_lt` (null is
189 // also safe to pass to this function, but we should never do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000190 sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800191 };
192 let greater_than = unsafe {
193 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
194 // this pointer is always safe to pass to `AIBinder_lt` (null is
195 // also safe to pass to this function, but we should never do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000196 sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800197 };
198 if !less_than && !greater_than {
199 Ordering::Equal
200 } else if less_than {
201 Ordering::Less
202 } else {
203 Ordering::Greater
204 }
205 }
206}
207
208impl PartialOrd for SpIBinder {
209 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
210 Some(self.cmp(other))
211 }
212}
213
Stephen Crane994a0f02020-08-11 14:47:29 -0700214impl PartialEq for SpIBinder {
215 fn eq(&self, other: &Self) -> bool {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000216 ptr::eq(self.0.as_ptr(), other.0.as_ptr())
Stephen Crane994a0f02020-08-11 14:47:29 -0700217 }
218}
219
220impl Eq for SpIBinder {}
221
Stephen Crane2a3c2502020-06-16 17:48:35 -0700222impl Clone for SpIBinder {
223 fn clone(&self) -> Self {
224 unsafe {
225 // Safety: Cloning a strong reference must increment the reference
226 // count. We are guaranteed by the `SpIBinder` constructor
227 // invariants that `self.0` is always a valid `AIBinder` pointer.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000228 sys::AIBinder_incStrong(self.0.as_ptr());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700229 }
230 Self(self.0)
231 }
232}
233
234impl Drop for SpIBinder {
235 // We hold a strong reference to the IBinder in SpIBinder and need to give up
236 // this reference on drop.
237 fn drop(&mut self) {
238 unsafe {
239 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
240 // know this pointer is safe to pass to `AIBinder_decStrong` here.
241 sys::AIBinder_decStrong(self.as_native_mut());
242 }
243 }
244}
245
Andrew Walbran12400d82021-03-04 17:04:34 +0000246impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
Alice Ryhl8618c482021-11-09 15:35:35 +0000247 fn prepare_transact(&self) -> Result<Parcel> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700248 let mut input = ptr::null_mut();
249 let status = unsafe {
250 // Safety: `SpIBinder` guarantees that `self` always contains a
251 // valid pointer to an `AIBinder`. It is safe to cast from an
252 // immutable pointer to a mutable pointer here, because
253 // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
254 // methods but the parameter is unfortunately not marked as const.
255 //
256 // After the call, input will be either a valid, owned `AParcel`
257 // pointer, or null.
258 sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
259 };
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000260
Stephen Crane2a3c2502020-06-16 17:48:35 -0700261 status_result(status)?;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000262
263 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700264 // Safety: At this point, `input` is either a valid, owned `AParcel`
Alice Ryhl268458c2021-09-15 12:56:10 +0000265 // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700266 // taking ownership of the parcel.
Alice Ryhl8618c482021-11-09 15:35:35 +0000267 Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000268 }
269 }
270
271 fn submit_transact(
272 &self,
273 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000274 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000275 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000276 ) -> Result<Parcel> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700277 let mut reply = ptr::null_mut();
278 let status = unsafe {
279 // Safety: `SpIBinder` guarantees that `self` always contains a
280 // valid pointer to an `AIBinder`. Although `IBinder::transact` is
281 // not a const method, it is still safe to cast our immutable
282 // pointer to mutable for the call. First, `IBinder::transact` is
283 // thread-safe, so concurrency is not an issue. The only way that
284 // `transact` can affect any visible, mutable state in the current
285 // process is by calling `onTransact` for a local service. However,
286 // in order for transactions to be thread-safe, this method must
287 // dynamically lock its data before modifying it. We enforce this
288 // property in Rust by requiring `Sync` for remotable objects and
289 // only providing `on_transact` with an immutable reference to
290 // `self`.
291 //
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000292 // This call takes ownership of the `data` parcel pointer, and
Stephen Crane2a3c2502020-06-16 17:48:35 -0700293 // passes ownership of the `reply` out parameter to its caller. It
294 // does not affect ownership of the `binder` parameter.
295 sys::AIBinder_transact(
296 self.as_native() as *mut sys::AIBinder,
297 code,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000298 &mut data.into_raw(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700299 &mut reply,
300 flags,
301 )
302 };
303 status_result(status)?;
304
305 unsafe {
306 // Safety: `reply` is either a valid `AParcel` pointer or null
307 // after the call to `AIBinder_transact` above, so we can
308 // construct a `Parcel` out of it. `AIBinder_transact` passes
309 // ownership of the `reply` parcel to Rust, so we need to
Alice Ryhl268458c2021-09-15 12:56:10 +0000310 // construct an owned variant.
Alice Ryhl8618c482021-11-09 15:35:35 +0000311 Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700312 }
313 }
314
315 fn is_binder_alive(&self) -> bool {
316 unsafe {
317 // Safety: `SpIBinder` guarantees that `self` always contains a
318 // valid pointer to an `AIBinder`.
319 //
320 // This call does not affect ownership of its pointer parameter.
321 sys::AIBinder_isAlive(self.as_native())
322 }
323 }
324
Janis Danisevskis1323d512021-11-09 07:48:08 -0800325 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700326 fn set_requesting_sid(&mut self, enable: bool) {
Andrew Walbran12400d82021-03-04 17:04:34 +0000327 unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700328 }
329
Stephen Crane2a3c2502020-06-16 17:48:35 -0700330 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
331 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
332 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
333 let status = unsafe {
334 // Safety: `SpIBinder` guarantees that `self` always contains a
335 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
336 // file descriptor parameter is always be a valid open file. The
337 // `args` pointer parameter is a valid pointer to an array of C
338 // strings that will outlive the call since `args` lives for the
339 // whole function scope.
340 //
341 // This call does not affect ownership of its binder pointer
342 // parameter and does not take ownership of the file or args array
343 // parameters.
344 sys::AIBinder_dump(
345 self.as_native_mut(),
346 fp.as_raw_fd(),
347 arg_ptrs.as_mut_ptr(),
348 arg_ptrs.len().try_into().unwrap(),
349 )
350 };
351 status_result(status)
352 }
353
354 fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
355 let mut out = ptr::null_mut();
356 let status = unsafe {
357 // Safety: `SpIBinder` guarantees that `self` always contains a
358 // valid pointer to an `AIBinder`. After this call, the `out`
359 // parameter will be either null, or a valid pointer to an
360 // `AIBinder`.
361 //
362 // This call passes ownership of the out pointer to its caller
363 // (assuming it is set to a non-null value).
364 sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
365 };
366 let ibinder = unsafe {
367 // Safety: The call above guarantees that `out` is either null or a
368 // valid, owned pointer to an `AIBinder`, both of which are safe to
369 // pass to `SpIBinder::from_raw`.
370 SpIBinder::from_raw(out)
371 };
372
373 status_result(status)?;
374 Ok(ibinder)
375 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000376}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700377
Andrew Walbran12400d82021-03-04 17:04:34 +0000378impl<T: AsNative<sys::AIBinder>> IBinder for T {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700379 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
380 status_result(unsafe {
381 // Safety: `SpIBinder` guarantees that `self` always contains a
382 // valid pointer to an `AIBinder`. `recipient` can always be
383 // converted into a valid pointer to an
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000384 // `AIBinder_DeathRecipient`.
385 //
386 // The cookie is also the correct pointer, and by calling new_cookie,
387 // we have created a new ref-count to the cookie, which linkToDeath
388 // takes ownership of. Once the DeathRecipient is unlinked for any
389 // reason (including if this call fails), the onUnlinked callback
390 // will consume that ref-count.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700391 sys::AIBinder_linkToDeath(
392 self.as_native_mut(),
393 recipient.as_native_mut(),
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000394 recipient.new_cookie(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700395 )
396 })
397 }
398
399 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
400 status_result(unsafe {
401 // Safety: `SpIBinder` guarantees that `self` always contains a
402 // valid pointer to an `AIBinder`. `recipient` can always be
403 // converted into a valid pointer to an
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800404 // `AIBinder_DeathRecipient`. Any value is safe to pass as the
Stephen Crane2a3c2502020-06-16 17:48:35 -0700405 // cookie, although we depend on this value being set by
406 // `get_cookie` when the death recipient callback is called.
407 sys::AIBinder_unlinkToDeath(
408 self.as_native_mut(),
409 recipient.as_native_mut(),
410 recipient.get_cookie(),
411 )
412 })
413 }
Stephen Crane61366d42022-01-20 17:45:34 -0800414
415 fn ping_binder(&mut self) -> Result<()> {
416 let status = unsafe {
417 // Safety: `SpIBinder` guarantees that `self` always contains a
418 // valid pointer to an `AIBinder`.
419 //
420 // This call does not affect ownership of its pointer parameter.
421 sys::AIBinder_ping(self.as_native_mut())
422 };
423 status_result(status)
424 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700425}
426
427impl Serialize for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000428 fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700429 parcel.write_binder(Some(self))
430 }
431}
432
433impl SerializeOption for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000434 fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700435 parcel.write_binder(this)
436 }
437}
438
439impl SerializeArray for SpIBinder {}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700440
441impl Deserialize for SpIBinder {
Andrei Homescu2b802f72023-05-05 03:21:43 +0000442 type UninitType = Option<Self>;
443 fn uninit() -> Self::UninitType {
444 Self::UninitType::default()
445 }
446 fn from_init(value: Self) -> Self::UninitType {
447 Some(value)
448 }
449
Alice Ryhl8618c482021-11-09 15:35:35 +0000450 fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700451 parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700452 }
453}
454
455impl DeserializeOption for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000456 fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700457 parcel.read_binder()
458 }
459}
460
461impl DeserializeArray for SpIBinder {}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700462
463/// A weak reference to a Binder remote object.
464///
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000465/// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
466/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000467pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700468
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000469impl fmt::Debug for WpIBinder {
470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471 f.pad("WpIBinder")
472 }
473}
474
475/// # Safety
476///
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700477/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000478unsafe impl Send for WpIBinder {}
479
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700480/// # Safety
481///
482/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
483unsafe impl Sync for WpIBinder {}
484
Stephen Crane2a3c2502020-06-16 17:48:35 -0700485impl WpIBinder {
486 /// Create a new weak reference from an object that can be converted into a
487 /// raw `AIBinder` pointer.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000488 fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700489 let ptr = unsafe {
490 // Safety: `SpIBinder` guarantees that `binder` always contains a
491 // valid pointer to an `AIBinder`.
492 sys::AIBinder_Weak_new(binder.as_native_mut())
493 };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000494 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700495 }
Stephen Crane994a0f02020-08-11 14:47:29 -0700496
497 /// Promote this weak reference to a strong reference to the binder object.
498 pub fn promote(&self) -> Option<SpIBinder> {
499 unsafe {
500 // Safety: `WpIBinder` always contains a valid weak reference, so we
501 // can pass this pointer to `AIBinder_Weak_promote`. Returns either
502 // null or an AIBinder owned by the caller, both of which are valid
503 // to pass to `SpIBinder::from_raw`.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000504 let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
Stephen Crane994a0f02020-08-11 14:47:29 -0700505 SpIBinder::from_raw(ptr)
506 }
507 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700508}
509
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800510impl Clone for WpIBinder {
511 fn clone(&self) -> Self {
512 let ptr = unsafe {
513 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
514 // so this pointer is always safe to pass to `AIBinder_Weak_clone`
515 // (although null is also a safe value to pass to this API).
516 //
517 // We get ownership of the returned pointer, so can construct a new
518 // WpIBinder object from it.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000519 sys::AIBinder_Weak_clone(self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800520 };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000521 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800522 }
523}
524
525impl Ord for WpIBinder {
526 fn cmp(&self, other: &Self) -> Ordering {
527 let less_than = unsafe {
528 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
529 // so this pointer is always safe to pass to `AIBinder_Weak_lt`
530 // (null is also safe to pass to this function, but we should never
531 // do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000532 sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800533 };
534 let greater_than = unsafe {
535 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
536 // so this pointer is always safe to pass to `AIBinder_Weak_lt`
537 // (null is also safe to pass to this function, but we should never
538 // do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000539 sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800540 };
541 if !less_than && !greater_than {
542 Ordering::Equal
543 } else if less_than {
544 Ordering::Less
545 } else {
546 Ordering::Greater
547 }
548 }
549}
550
551impl PartialOrd for WpIBinder {
552 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
553 Some(self.cmp(other))
554 }
555}
556
557impl PartialEq for WpIBinder {
558 fn eq(&self, other: &Self) -> bool {
559 self.cmp(other) == Ordering::Equal
560 }
561}
562
563impl Eq for WpIBinder {}
564
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000565impl Drop for WpIBinder {
566 fn drop(&mut self) {
567 unsafe {
568 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
569 // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000570 sys::AIBinder_Weak_delete(self.0.as_ptr());
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000571 }
572 }
573}
574
Stephen Crane2a3c2502020-06-16 17:48:35 -0700575/// Rust wrapper around DeathRecipient objects.
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000576///
577/// The cookie in this struct represents an Arc<F> for the owned callback.
578/// This struct owns a ref-count of it, and so does every binder that we
579/// have been linked with.
Matthew Maurera7eb0d42022-07-26 10:07:05 -0700580///
581/// Dropping the `DeathRecipient` will `unlink_to_death` any binders it is
582/// currently linked to.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700583#[repr(C)]
584pub struct DeathRecipient {
585 recipient: *mut sys::AIBinder_DeathRecipient,
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000586 cookie: *mut c_void,
587 vtable: &'static DeathRecipientVtable,
588}
589
590struct DeathRecipientVtable {
591 cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
592 cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700593}
594
Matthew Maurer51d76c82022-04-04 14:27:01 -0700595/// # Safety
596///
597/// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
598/// to a `Fn` which is `Sync` and `Send` (the cookie field). As
599/// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
600unsafe impl Send for DeathRecipient {}
601
602/// # Safety
603///
604/// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
605/// to a `Fn` which is `Sync` and `Send` (the cookie field). As
606/// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
607unsafe impl Sync for DeathRecipient {}
608
Stephen Crane2a3c2502020-06-16 17:48:35 -0700609impl DeathRecipient {
610 /// Create a new death recipient that will call the given callback when its
611 /// associated object dies.
612 pub fn new<F>(callback: F) -> DeathRecipient
613 where
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000614 F: Fn() + Send + Sync + 'static,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700615 {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000616 let callback: *const F = Arc::into_raw(Arc::new(callback));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700617 let recipient = unsafe {
618 // Safety: The function pointer is a valid death recipient callback.
619 //
620 // This call returns an owned `AIBinder_DeathRecipient` pointer
621 // which must be destroyed via `AIBinder_DeathRecipient_delete` when
622 // no longer needed.
623 sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
624 };
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000625 unsafe {
626 // Safety: The function pointer is a valid onUnlinked callback.
627 //
628 // All uses of linkToDeath in this file correctly increment the
629 // ref-count that this onUnlinked callback will decrement.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700630 sys::AIBinder_DeathRecipient_setOnUnlinked(
631 recipient,
632 Some(Self::cookie_decr_refcount::<F>),
633 );
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000634 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700635 DeathRecipient {
636 recipient,
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000637 cookie: callback as *mut c_void,
638 vtable: &DeathRecipientVtable {
639 cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
640 cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
641 },
Stephen Crane2a3c2502020-06-16 17:48:35 -0700642 }
643 }
644
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000645 /// Increment the ref-count for the cookie and return it.
646 ///
647 /// # Safety
648 ///
649 /// The caller must handle the returned ref-count correctly.
650 unsafe fn new_cookie(&self) -> *mut c_void {
651 (self.vtable.cookie_incr_refcount)(self.cookie);
652
653 // Return a raw pointer with ownership of a ref-count
654 self.cookie
655 }
656
Stephen Crane2a3c2502020-06-16 17:48:35 -0700657 /// Get the opaque cookie that identifies this death recipient.
658 ///
659 /// This cookie will be used to link and unlink this death recipient to a
660 /// binder object and will be passed to the `binder_died` callback as an
661 /// opaque userdata pointer.
662 fn get_cookie(&self) -> *mut c_void {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000663 self.cookie
Stephen Crane2a3c2502020-06-16 17:48:35 -0700664 }
665
666 /// Callback invoked from C++ when the binder object dies.
667 ///
668 /// # Safety
669 ///
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000670 /// The `cookie` parameter must be the cookie for an Arc<F> and
671 /// the caller must hold a ref-count to it.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700672 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
673 where
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000674 F: Fn() + Send + Sync + 'static,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700675 {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000676 let callback = (cookie as *const F).as_ref().unwrap();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700677 callback();
678 }
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000679
680 /// Callback that decrements the ref-count.
681 /// This is invoked from C++ when a binder is unlinked.
682 ///
683 /// # Safety
684 ///
685 /// The `cookie` parameter must be the cookie for an Arc<F> and
686 /// the owner must give up a ref-count to it.
687 unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
688 where
689 F: Fn() + Send + Sync + 'static,
690 {
691 drop(Arc::from_raw(cookie as *const F));
692 }
693
694 /// Callback that increments the ref-count.
695 ///
696 /// # Safety
697 ///
698 /// The `cookie` parameter must be the cookie for an Arc<F> and
699 /// the owner must handle the created ref-count properly.
700 unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
701 where
702 F: Fn() + Send + Sync + 'static,
703 {
704 let arc = mem::ManuallyDrop::new(Arc::from_raw(cookie as *const F));
705 mem::forget(Arc::clone(&arc));
706 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700707}
708
709/// # Safety
710///
711/// A `DeathRecipient` is always constructed with a valid raw pointer to an
712/// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
713/// pointer.
714unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
715 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
716 self.recipient
717 }
718
719 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
720 self.recipient
721 }
722}
723
724impl Drop for DeathRecipient {
725 fn drop(&mut self) {
726 unsafe {
727 // Safety: `self.recipient` is always a valid, owned
728 // `AIBinder_DeathRecipient` pointer returned by
729 // `AIBinder_DeathRecipient_new` when `self` was created. This
730 // delete method can only be called once when `self` is dropped.
731 sys::AIBinder_DeathRecipient_delete(self.recipient);
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000732
733 // Safety: We own a ref-count to the cookie, and so does every
734 // linked binder. This call gives up our ref-count. The linked
735 // binders should already have given up their ref-count, or should
736 // do so shortly.
737 (self.vtable.cookie_decr_refcount)(self.cookie)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700738 }
739 }
740}
741
742/// Generic interface to remote binder objects.
743///
744/// Corresponds to the C++ `BpInterface` class.
745pub trait Proxy: Sized + Interface {
746 /// The Binder interface descriptor string.
747 ///
748 /// This string is a unique identifier for a Binder interface, and should be
749 /// the same between all implementations of that interface.
750 fn get_descriptor() -> &'static str;
751
752 /// Create a new interface from the given proxy, if it matches the expected
753 /// type of this interface.
754 fn from_binder(binder: SpIBinder) -> Result<Self>;
755}
756
757/// # Safety
758///
759/// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
760/// invocation of `IBinder` methods directly from `Interface` objects. It shares
761/// the same safety as the implementation for `SpIBinder`.
762unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
763 fn as_native(&self) -> *const sys::AIBinder {
764 self.as_binder().as_native()
765 }
766
767 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
768 self.as_binder().as_native_mut()
769 }
770}
771
772/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
773/// exist.
774pub fn get_service(name: &str) -> Option<SpIBinder> {
775 let name = CString::new(name).ok()?;
776 unsafe {
777 // Safety: `AServiceManager_getService` returns either a null pointer or
778 // a valid pointer to an owned `AIBinder`. Either of these values is
779 // safe to pass to `SpIBinder::from_raw`.
780 SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
781 }
782}
783
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000784/// Retrieve an existing service, or start it if it is configured as a dynamic
785/// service and isn't yet started.
786pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
787 let name = CString::new(name).ok()?;
788 unsafe {
789 // Safety: `AServiceManager_waitforService` returns either a null
790 // pointer or a valid pointer to an owned `AIBinder`. Either of these
791 // values is safe to pass to `SpIBinder::from_raw`.
792 SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
793 }
794}
795
Stephen Crane2a3c2502020-06-16 17:48:35 -0700796/// Retrieve an existing service for a particular interface, blocking for a few
797/// seconds if it doesn't yet exist.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800798pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
Andrew Walbranff136e02022-08-02 17:16:12 +0000799 interface_cast(get_service(name))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700800}
801
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000802/// Retrieve an existing service for a particular interface, or start it if it
803/// is configured as a dynamic service and isn't yet started.
804pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
Andrew Walbranff136e02022-08-02 17:16:12 +0000805 interface_cast(wait_for_service(name))
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000806}
807
Stephen Crane098bbc92022-02-14 13:31:53 -0800808/// Check if a service is declared (e.g. in a VINTF manifest)
809pub fn is_declared(interface: &str) -> Result<bool> {
810 let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
811
812 unsafe {
813 // Safety: `interface` is a valid null-terminated C-style string and is
814 // only borrowed for the lifetime of the call. The `interface` local
815 // outlives this call as it lives for the function scope.
816 Ok(sys::AServiceManager_isDeclared(interface.as_ptr()))
817 }
818}
819
820/// Retrieve all declared instances for a particular interface
821///
822/// For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo'
823/// is passed here, then ["foo"] would be returned.
824pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
825 unsafe extern "C" fn callback(instance: *const c_char, opaque: *mut c_void) {
826 // Safety: opaque was a mutable pointer created below from a Vec of
827 // CString, and outlives this callback. The null handling here is just
828 // to avoid the possibility of unwinding across C code if this crate is
829 // ever compiled with panic=unwind.
830 if let Some(instances) = opaque.cast::<Vec<CString>>().as_mut() {
831 // Safety: instance is a valid null-terminated C string with a
832 // lifetime at least as long as this function, and we immediately
833 // copy it into an owned CString.
834 instances.push(CStr::from_ptr(instance).to_owned());
835 } else {
836 eprintln!("Opaque pointer was null in get_declared_instances callback!");
837 }
838 }
839
840 let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
841 let mut instances: Vec<CString> = vec![];
842 unsafe {
843 // Safety: `interface` and `instances` are borrowed for the length of
844 // this call and both outlive the call. `interface` is guaranteed to be
845 // a valid null-terminated C-style string.
846 sys::AServiceManager_forEachDeclaredInstance(
847 interface.as_ptr(),
848 &mut instances as *mut _ as *mut c_void,
849 Some(callback),
850 );
851 }
852
853 instances
854 .into_iter()
855 .map(CString::into_string)
856 .collect::<std::result::Result<Vec<String>, _>>()
857 .map_err(|e| {
858 eprintln!("An interface instance name was not a valid UTF-8 string: {}", e);
859 StatusCode::BAD_VALUE
860 })
861}
862
Stephen Crane2a3c2502020-06-16 17:48:35 -0700863/// # Safety
864///
865/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
866/// `AIBinder`, so we can trivially extract this pointer here.
867unsafe impl AsNative<sys::AIBinder> for SpIBinder {
868 fn as_native(&self) -> *const sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000869 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700870 }
871
872 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000873 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700874 }
875}