• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 use crate::binder::{
20     AsNative, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Strong,
21     TransactionCode, TransactionFlags,
22 };
23 use crate::error::{status_result, Result, StatusCode};
24 use crate::parcel::{
25     BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize,
26     SerializeArray, SerializeOption,
27 };
28 use crate::sys;
29 
30 use std::cmp::Ordering;
31 use std::convert::TryInto;
32 use std::ffi::{c_void, CString};
33 use std::fmt;
34 use std::mem;
35 use std::os::fd::AsRawFd;
36 use std::ptr;
37 use std::sync::Arc;
38 
39 /// A strong reference to a Binder remote object.
40 ///
41 /// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
42 /// is untyped; typed interface access is implemented by the AIDL compiler.
43 pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
44 
45 impl fmt::Debug for SpIBinder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result46     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47         f.pad("SpIBinder")
48     }
49 }
50 
51 /// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is
52 /// thread-safe.
53 unsafe impl Send for SpIBinder {}
54 
55 /// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is
56 /// thread-safe.
57 unsafe impl Sync for SpIBinder {}
58 
59 impl SpIBinder {
60     /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
61     ///
62     /// # Safety
63     ///
64     /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
65     /// to an `AIBinder`.
66     ///
67     /// In the non-null case, this method conceptually takes ownership of a strong
68     /// reference to the object, so `AIBinder_incStrong` must have been called
69     /// on the pointer before passing it to this constructor. This is generally
70     /// done by Binder NDK methods that return an `AIBinder`, but care should be
71     /// taken to ensure this invariant.
72     ///
73     /// All `SpIBinder` objects that are constructed will hold a valid pointer
74     /// to an `AIBinder`, which will remain valid for the entire lifetime of the
75     /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
from_raw(ptr: *mut sys::AIBinder) -> Option<Self>76     pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
77         ptr::NonNull::new(ptr).map(Self)
78     }
79 
80     /// Extract a raw `AIBinder` pointer from this wrapper.
81     ///
82     /// This method should _only_ be used for testing. Do not try to use the NDK
83     /// interface directly for anything else.
84     ///
85     /// # Safety
86     ///
87     /// The resulting pointer is valid only as long as the SpIBinder is alive.
88     /// The SpIBinder object retains ownership of the AIBinder and the caller
89     /// should not attempt to free the returned pointer.
as_raw(&self) -> *mut sys::AIBinder90     pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
91         self.0.as_ptr()
92     }
93 
94     /// Return true if this binder object is hosted in a different process than
95     /// the current one.
is_remote(&self) -> bool96     pub fn is_remote(&self) -> bool {
97         // Safety: `SpIBinder` guarantees that it always contains a valid
98         // `AIBinder` pointer.
99         unsafe { sys::AIBinder_isRemote(self.as_native()) }
100     }
101 
102     /// Try to convert this Binder object into a trait object for the given
103     /// Binder interface.
104     ///
105     /// If this object does not implement the expected interface, the error
106     /// `StatusCode::BAD_TYPE` is returned.
into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>>107     pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
108         FromIBinder::try_from(self)
109     }
110 
111     /// Return the interface class of this binder object, if associated with
112     /// one.
get_class(&mut self) -> Option<InterfaceClass>113     pub fn get_class(&mut self) -> Option<InterfaceClass> {
114         // Safety: `SpIBinder` guarantees that it always contains a valid
115         // `AIBinder` pointer. `AIBinder_getClass` returns either a null
116         // pointer or a valid pointer to an `AIBinder_Class`. After mapping
117         // null to None, we can safely construct an `InterfaceClass` if the
118         // pointer was non-null.
119         unsafe {
120             let class = sys::AIBinder_getClass(self.as_native_mut());
121             class.as_ref().map(|p| InterfaceClass::from_ptr(p))
122         }
123     }
124 
125     /// Creates a new weak reference to this binder object.
downgrade(&mut self) -> WpIBinder126     pub fn downgrade(&mut self) -> WpIBinder {
127         WpIBinder::new(self)
128     }
129 }
130 
131 pub mod unstable_api {
132     use super::{sys, SpIBinder};
133 
134     /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
135     /// needed to bridge RPC binder, which doesn't have Rust API yet.
136     /// TODO(b/184872979): remove once the Rust API is created.
137     ///
138     /// # Safety
139     ///
140     /// See `SpIBinder::from_raw`.
new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder>141     pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
142         // Safety: The caller makes the same guarantees as this requires.
143         unsafe { SpIBinder::from_raw(ptr) }
144     }
145 }
146 
147 /// An object that can be associate with an [`InterfaceClass`].
148 pub trait AssociateClass {
149     /// Check if this object is a valid object for the given interface class
150     /// `I`.
151     ///
152     /// Returns `Some(self)` if this is a valid instance of the interface, and
153     /// `None` otherwise.
154     ///
155     /// Classes constructed by `InterfaceClass` are unique per type, so
156     /// repeatedly calling this method for the same `InterfaceClass` is allowed.
associate_class(&mut self, class: InterfaceClass) -> bool157     fn associate_class(&mut self, class: InterfaceClass) -> bool;
158 }
159 
160 impl AssociateClass for SpIBinder {
associate_class(&mut self, class: InterfaceClass) -> bool161     fn associate_class(&mut self, class: InterfaceClass) -> bool {
162         // Safety: `SpIBinder` guarantees that it always contains a valid
163         // `AIBinder` pointer. An `InterfaceClass` can always be converted
164         // into a valid `AIBinder_Class` pointer, so these parameters are
165         // always safe.
166         unsafe { sys::AIBinder_associateClass(self.as_native_mut(), class.into()) }
167     }
168 }
169 
170 impl Ord for SpIBinder {
cmp(&self, other: &Self) -> Ordering171     fn cmp(&self, other: &Self) -> Ordering {
172         // Safety: SpIBinder always holds a valid `AIBinder` pointer, so this
173         // pointer is always safe to pass to `AIBinder_lt` (null is also safe to
174         // pass to this function, but we should never do that).
175         let less_than = unsafe { sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr()) };
176         // Safety: SpIBinder always holds a valid `AIBinder` pointer, so this
177         // pointer is always safe to pass to `AIBinder_lt` (null is also safe to
178         // pass to this function, but we should never do that).
179         let greater_than = unsafe { sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr()) };
180         if !less_than && !greater_than {
181             Ordering::Equal
182         } else if less_than {
183             Ordering::Less
184         } else {
185             Ordering::Greater
186         }
187     }
188 }
189 
190 impl PartialOrd for SpIBinder {
partial_cmp(&self, other: &Self) -> Option<Ordering>191     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
192         Some(self.cmp(other))
193     }
194 }
195 
196 impl PartialEq for SpIBinder {
eq(&self, other: &Self) -> bool197     fn eq(&self, other: &Self) -> bool {
198         ptr::eq(self.0.as_ptr(), other.0.as_ptr())
199     }
200 }
201 
202 impl Eq for SpIBinder {}
203 
204 impl Clone for SpIBinder {
clone(&self) -> Self205     fn clone(&self) -> Self {
206         // Safety: Cloning a strong reference must increment the reference
207         // count. We are guaranteed by the `SpIBinder` constructor
208         // invariants that `self.0` is always a valid `AIBinder` pointer.
209         unsafe {
210             sys::AIBinder_incStrong(self.0.as_ptr());
211         }
212         Self(self.0)
213     }
214 }
215 
216 impl Drop for SpIBinder {
217     // We hold a strong reference to the IBinder in SpIBinder and need to give up
218     // this reference on drop.
drop(&mut self)219     fn drop(&mut self) {
220         // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
221         // know this pointer is safe to pass to `AIBinder_decStrong` here.
222         unsafe {
223             sys::AIBinder_decStrong(self.as_native_mut());
224         }
225     }
226 }
227 
228 impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
prepare_transact(&self) -> Result<Parcel>229     fn prepare_transact(&self) -> Result<Parcel> {
230         let mut input = ptr::null_mut();
231         // Safety: `SpIBinder` guarantees that `self` always contains a
232         // valid pointer to an `AIBinder`. It is safe to cast from an
233         // immutable pointer to a mutable pointer here, because
234         // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
235         // methods but the parameter is unfortunately not marked as const.
236         //
237         // After the call, input will be either a valid, owned `AParcel`
238         // pointer, or null.
239         let status = unsafe {
240             sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
241         };
242 
243         status_result(status)?;
244 
245         // Safety: At this point, `input` is either a valid, owned `AParcel`
246         // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
247         // taking ownership of the parcel.
248         unsafe { Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL) }
249     }
250 
submit_transact( &self, code: TransactionCode, data: Parcel, flags: TransactionFlags, ) -> Result<Parcel>251     fn submit_transact(
252         &self,
253         code: TransactionCode,
254         data: Parcel,
255         flags: TransactionFlags,
256     ) -> Result<Parcel> {
257         let mut reply = ptr::null_mut();
258         // Safety: `SpIBinder` guarantees that `self` always contains a
259         // valid pointer to an `AIBinder`. Although `IBinder::transact` is
260         // not a const method, it is still safe to cast our immutable
261         // pointer to mutable for the call. First, `IBinder::transact` is
262         // thread-safe, so concurrency is not an issue. The only way that
263         // `transact` can affect any visible, mutable state in the current
264         // process is by calling `onTransact` for a local service. However,
265         // in order for transactions to be thread-safe, this method must
266         // dynamically lock its data before modifying it. We enforce this
267         // property in Rust by requiring `Sync` for remotable objects and
268         // only providing `on_transact` with an immutable reference to
269         // `self`.
270         //
271         // This call takes ownership of the `data` parcel pointer, and
272         // passes ownership of the `reply` out parameter to its caller. It
273         // does not affect ownership of the `binder` parameter.
274         let status = unsafe {
275             sys::AIBinder_transact(
276                 self.as_native() as *mut sys::AIBinder,
277                 code,
278                 &mut data.into_raw(),
279                 &mut reply,
280                 flags,
281             )
282         };
283         status_result(status)?;
284 
285         // Safety: `reply` is either a valid `AParcel` pointer or null
286         // after the call to `AIBinder_transact` above, so we can
287         // construct a `Parcel` out of it. `AIBinder_transact` passes
288         // ownership of the `reply` parcel to Rust, so we need to
289         // construct an owned variant.
290         unsafe { Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL) }
291     }
292 
is_binder_alive(&self) -> bool293     fn is_binder_alive(&self) -> bool {
294         // Safety: `SpIBinder` guarantees that `self` always contains a valid
295         // pointer to an `AIBinder`.
296         //
297         // This call does not affect ownership of its pointer parameter.
298         unsafe { sys::AIBinder_isAlive(self.as_native()) }
299     }
300 
301     #[cfg(not(android_vndk))]
set_requesting_sid(&mut self, enable: bool)302     fn set_requesting_sid(&mut self, enable: bool) {
303         // Safety: `SpIBinder` guarantees that `self` always contains a valid
304         // pointer to an `AIBinder`.
305         //
306         // This call does not affect ownership of its pointer parameter.
307         unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
308     }
309 
dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>310     fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
311         let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
312         let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
313         // Safety: `SpIBinder` guarantees that `self` always contains a
314         // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
315         // file descriptor parameter is always be a valid open file. The
316         // `args` pointer parameter is a valid pointer to an array of C
317         // strings that will outlive the call since `args` lives for the
318         // whole function scope.
319         //
320         // This call does not affect ownership of its binder pointer
321         // parameter and does not take ownership of the file or args array
322         // parameters.
323         let status = unsafe {
324             sys::AIBinder_dump(
325                 self.as_native_mut(),
326                 fp.as_raw_fd(),
327                 arg_ptrs.as_mut_ptr(),
328                 arg_ptrs.len().try_into().unwrap(),
329             )
330         };
331         status_result(status)
332     }
333 
get_extension(&mut self) -> Result<Option<SpIBinder>>334     fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
335         let mut out = ptr::null_mut();
336         // Safety: `SpIBinder` guarantees that `self` always contains a
337         // valid pointer to an `AIBinder`. After this call, the `out`
338         // parameter will be either null, or a valid pointer to an
339         // `AIBinder`.
340         //
341         // This call passes ownership of the out pointer to its caller
342         // (assuming it is set to a non-null value).
343         let status = unsafe { sys::AIBinder_getExtension(self.as_native_mut(), &mut out) };
344         // Safety: The call above guarantees that `out` is either null or a
345         // valid, owned pointer to an `AIBinder`, both of which are safe to
346         // pass to `SpIBinder::from_raw`.
347         let ibinder = unsafe { SpIBinder::from_raw(out) };
348 
349         status_result(status)?;
350         Ok(ibinder)
351     }
352 }
353 
354 impl<T: AsNative<sys::AIBinder>> IBinder for T {
link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>355     fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
356         // Safety: `SpIBinder` guarantees that `self` always contains a
357         // valid pointer to an `AIBinder`. `recipient` can always be
358         // converted into a valid pointer to an
359         // `AIBinder_DeathRecipient`.
360         //
361         // The cookie is also the correct pointer, and by calling new_cookie,
362         // we have created a new ref-count to the cookie, which linkToDeath
363         // takes ownership of. Once the DeathRecipient is unlinked for any
364         // reason (including if this call fails), the onUnlinked callback
365         // will consume that ref-count.
366         status_result(unsafe {
367             sys::AIBinder_linkToDeath(
368                 self.as_native_mut(),
369                 recipient.as_native_mut(),
370                 recipient.new_cookie(),
371             )
372         })
373     }
374 
unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>375     fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
376         // Safety: `SpIBinder` guarantees that `self` always contains a
377         // valid pointer to an `AIBinder`. `recipient` can always be
378         // converted into a valid pointer to an
379         // `AIBinder_DeathRecipient`. Any value is safe to pass as the
380         // cookie, although we depend on this value being set by
381         // `get_cookie` when the death recipient callback is called.
382         status_result(unsafe {
383             sys::AIBinder_unlinkToDeath(
384                 self.as_native_mut(),
385                 recipient.as_native_mut(),
386                 recipient.get_cookie(),
387             )
388         })
389     }
390 
ping_binder(&mut self) -> Result<()>391     fn ping_binder(&mut self) -> Result<()> {
392         // Safety: `SpIBinder` guarantees that `self` always contains a
393         // valid pointer to an `AIBinder`.
394         //
395         // This call does not affect ownership of its pointer parameter.
396         let status = unsafe { sys::AIBinder_ping(self.as_native_mut()) };
397         status_result(status)
398     }
399 }
400 
401 impl Serialize for SpIBinder {
serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>402     fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
403         parcel.write_binder(Some(self))
404     }
405 }
406 
407 impl SerializeOption for SpIBinder {
serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()>408     fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
409         parcel.write_binder(this)
410     }
411 }
412 
413 impl SerializeArray for SpIBinder {}
414 
415 impl Deserialize for SpIBinder {
416     type UninitType = Option<Self>;
uninit() -> Self::UninitType417     fn uninit() -> Self::UninitType {
418         Self::UninitType::default()
419     }
from_init(value: Self) -> Self::UninitType420     fn from_init(value: Self) -> Self::UninitType {
421         Some(value)
422     }
423 
deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder>424     fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
425         parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
426     }
427 }
428 
429 impl DeserializeOption for SpIBinder {
deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>>430     fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
431         parcel.read_binder()
432     }
433 }
434 
435 impl DeserializeArray for SpIBinder {}
436 
437 /// A weak reference to a Binder remote object.
438 ///
439 /// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
440 /// is untyped; typed interface access is implemented by the AIDL compiler.
441 pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
442 
443 impl fmt::Debug for WpIBinder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result444     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445         f.pad("WpIBinder")
446     }
447 }
448 
449 /// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is
450 /// thread-safe.
451 unsafe impl Send for WpIBinder {}
452 
453 /// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is
454 /// thread-safe.
455 unsafe impl Sync for WpIBinder {}
456 
457 impl WpIBinder {
458     /// Create a new weak reference from an object that can be converted into a
459     /// raw `AIBinder` pointer.
new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder460     fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
461         // Safety: `SpIBinder` guarantees that `binder` always contains a valid
462         // pointer to an `AIBinder`.
463         let ptr = unsafe { sys::AIBinder_Weak_new(binder.as_native_mut()) };
464         Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
465     }
466 
467     /// Promote this weak reference to a strong reference to the binder object.
promote(&self) -> Option<SpIBinder>468     pub fn promote(&self) -> Option<SpIBinder> {
469         // Safety: `WpIBinder` always contains a valid weak reference, so we can
470         // pass this pointer to `AIBinder_Weak_promote`. Returns either null or
471         // an AIBinder owned by the caller, both of which are valid to pass to
472         // `SpIBinder::from_raw`.
473         unsafe {
474             let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
475             SpIBinder::from_raw(ptr)
476         }
477     }
478 }
479 
480 impl Clone for WpIBinder {
clone(&self) -> Self481     fn clone(&self) -> Self {
482         // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so
483         // this pointer is always safe to pass to `AIBinder_Weak_clone`
484         // (although null is also a safe value to pass to this API).
485         //
486         // We get ownership of the returned pointer, so can construct a new
487         // WpIBinder object from it.
488         let ptr = unsafe { sys::AIBinder_Weak_clone(self.0.as_ptr()) };
489         Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
490     }
491 }
492 
493 impl Ord for WpIBinder {
cmp(&self, other: &Self) -> Ordering494     fn cmp(&self, other: &Self) -> Ordering {
495         // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so
496         // this pointer is always safe to pass to `AIBinder_Weak_lt` (null is
497         // also safe to pass to this function, but we should never do that).
498         let less_than = unsafe { sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr()) };
499         // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so
500         // this pointer is always safe to pass to `AIBinder_Weak_lt` (null is
501         // also safe to pass to this function, but we should never do that).
502         let greater_than = unsafe { sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr()) };
503         if !less_than && !greater_than {
504             Ordering::Equal
505         } else if less_than {
506             Ordering::Less
507         } else {
508             Ordering::Greater
509         }
510     }
511 }
512 
513 impl PartialOrd for WpIBinder {
partial_cmp(&self, other: &Self) -> Option<Ordering>514     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
515         Some(self.cmp(other))
516     }
517 }
518 
519 impl PartialEq for WpIBinder {
eq(&self, other: &Self) -> bool520     fn eq(&self, other: &Self) -> bool {
521         self.cmp(other) == Ordering::Equal
522     }
523 }
524 
525 impl Eq for WpIBinder {}
526 
527 impl Drop for WpIBinder {
drop(&mut self)528     fn drop(&mut self) {
529         // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
530         // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
531         unsafe {
532             sys::AIBinder_Weak_delete(self.0.as_ptr());
533         }
534     }
535 }
536 
537 /// Rust wrapper around DeathRecipient objects.
538 ///
539 /// The cookie in this struct represents an `Arc<F>` for the owned callback.
540 /// This struct owns a ref-count of it, and so does every binder that we
541 /// have been linked with.
542 ///
543 /// Dropping the `DeathRecipient` will `unlink_to_death` any binders it is
544 /// currently linked to.
545 #[repr(C)]
546 pub struct DeathRecipient {
547     recipient: *mut sys::AIBinder_DeathRecipient,
548     cookie: *mut c_void,
549     vtable: &'static DeathRecipientVtable,
550 }
551 
552 struct DeathRecipientVtable {
553     cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
554     cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
555 }
556 
557 /// Safety: A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and
558 /// a pointer to a `Fn` which is `Sync` and `Send` (the cookie field). As
559 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
560 unsafe impl Send for DeathRecipient {}
561 
562 /// Safety: A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and
563 /// a pointer to a `Fn` which is `Sync` and `Send` (the cookie field). As
564 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
565 unsafe impl Sync for DeathRecipient {}
566 
567 impl DeathRecipient {
568     /// Create a new death recipient that will call the given callback when its
569     /// associated object dies.
new<F>(callback: F) -> DeathRecipient where F: Fn() + Send + Sync + 'static,570     pub fn new<F>(callback: F) -> DeathRecipient
571     where
572         F: Fn() + Send + Sync + 'static,
573     {
574         let callback: *const F = Arc::into_raw(Arc::new(callback));
575         // Safety: The function pointer is a valid death recipient callback.
576         //
577         // This call returns an owned `AIBinder_DeathRecipient` pointer which
578         // must be destroyed via `AIBinder_DeathRecipient_delete` when no longer
579         // needed.
580         let recipient = unsafe { sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>)) };
581         // Safety: The function pointer is a valid onUnlinked callback.
582         //
583         // All uses of linkToDeath in this file correctly increment the
584         // ref-count that this onUnlinked callback will decrement.
585         unsafe {
586             sys::AIBinder_DeathRecipient_setOnUnlinked(
587                 recipient,
588                 Some(Self::cookie_decr_refcount::<F>),
589             );
590         }
591         DeathRecipient {
592             recipient,
593             cookie: callback as *mut c_void,
594             vtable: &DeathRecipientVtable {
595                 cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
596                 cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
597             },
598         }
599     }
600 
601     /// Increment the ref-count for the cookie and return it.
602     ///
603     /// # Safety
604     ///
605     /// The caller must handle the returned ref-count correctly.
new_cookie(&self) -> *mut c_void606     unsafe fn new_cookie(&self) -> *mut c_void {
607         // Safety: `cookie_incr_refcount` points to
608         // `Self::cookie_incr_refcount`, and `self.cookie` is the cookie for an
609         // Arc<F>.
610         unsafe {
611             (self.vtable.cookie_incr_refcount)(self.cookie);
612         }
613 
614         // Return a raw pointer with ownership of a ref-count
615         self.cookie
616     }
617 
618     /// Get the opaque cookie that identifies this death recipient.
619     ///
620     /// This cookie will be used to link and unlink this death recipient to a
621     /// binder object and will be passed to the `binder_died` callback as an
622     /// opaque userdata pointer.
get_cookie(&self) -> *mut c_void623     fn get_cookie(&self) -> *mut c_void {
624         self.cookie
625     }
626 
627     /// Callback invoked from C++ when the binder object dies.
628     ///
629     /// # Safety
630     ///
631     /// The `cookie` parameter must be the cookie for an `Arc<F>` and
632     /// the caller must hold a ref-count to it.
binder_died<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,633     unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
634     where
635         F: Fn() + Send + Sync + 'static,
636     {
637         // Safety: The caller promises that `cookie` is for an Arc<F>.
638         let callback = unsafe { (cookie as *const F).as_ref().unwrap() };
639         callback();
640     }
641 
642     /// Callback that decrements the ref-count.
643     /// This is invoked from C++ when a binder is unlinked.
644     ///
645     /// # Safety
646     ///
647     /// The `cookie` parameter must be the cookie for an `Arc<F>` and
648     /// the owner must give up a ref-count to it.
cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,649     unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
650     where
651         F: Fn() + Send + Sync + 'static,
652     {
653         // Safety: The caller promises that `cookie` is for an Arc<F>.
654         drop(unsafe { Arc::from_raw(cookie as *const F) });
655     }
656 
657     /// Callback that increments the ref-count.
658     ///
659     /// # Safety
660     ///
661     /// The `cookie` parameter must be the cookie for an `Arc<F>` and
662     /// the owner must handle the created ref-count properly.
cookie_incr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,663     unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
664     where
665         F: Fn() + Send + Sync + 'static,
666     {
667         // Safety: The caller promises that `cookie` is for an Arc<F>.
668         let arc = mem::ManuallyDrop::new(unsafe { Arc::from_raw(cookie as *const F) });
669         mem::forget(Arc::clone(&arc));
670     }
671 }
672 
673 /// Safety: A `DeathRecipient` is always constructed with a valid raw pointer to
674 /// an `AIBinder_DeathRecipient`, so it is always type-safe to extract this
675 /// pointer.
676 unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
as_native(&self) -> *const sys::AIBinder_DeathRecipient677     fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
678         self.recipient
679     }
680 
as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient681     fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
682         self.recipient
683     }
684 }
685 
686 impl Drop for DeathRecipient {
drop(&mut self)687     fn drop(&mut self) {
688         // Safety: `self.recipient` is always a valid, owned
689         // `AIBinder_DeathRecipient` pointer returned by
690         // `AIBinder_DeathRecipient_new` when `self` was created. This delete
691         // method can only be called once when `self` is dropped.
692         unsafe {
693             sys::AIBinder_DeathRecipient_delete(self.recipient);
694         }
695 
696         // Safety: We own a ref-count to the cookie, and so does every linked
697         // binder. This call gives up our ref-count. The linked binders should
698         // already have given up their ref-count, or should do so shortly.
699         unsafe {
700             (self.vtable.cookie_decr_refcount)(self.cookie);
701         }
702     }
703 }
704 
705 /// Generic interface to remote binder objects.
706 ///
707 /// Corresponds to the C++ `BpInterface` class.
708 pub trait Proxy: Sized + Interface {
709     /// The Binder interface descriptor string.
710     ///
711     /// This string is a unique identifier for a Binder interface, and should be
712     /// the same between all implementations of that interface.
get_descriptor() -> &'static str713     fn get_descriptor() -> &'static str;
714 
715     /// Create a new interface from the given proxy, if it matches the expected
716     /// type of this interface.
from_binder(binder: SpIBinder) -> Result<Self>717     fn from_binder(binder: SpIBinder) -> Result<Self>;
718 }
719 
720 /// Safety: This is a convenience method that wraps `AsNative` for `SpIBinder`
721 /// to allow invocation of `IBinder` methods directly from `Interface` objects.
722 /// It shares the same safety as the implementation for `SpIBinder`.
723 unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
as_native(&self) -> *const sys::AIBinder724     fn as_native(&self) -> *const sys::AIBinder {
725         self.as_binder().as_native()
726     }
727 
as_native_mut(&mut self) -> *mut sys::AIBinder728     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
729         self.as_binder().as_native_mut()
730     }
731 }
732 
733 /// Safety: `SpIBinder` guarantees that `binder` always contains a valid pointer
734 /// to an `AIBinder`, so we can trivially extract this pointer here.
735 unsafe impl AsNative<sys::AIBinder> for SpIBinder {
as_native(&self) -> *const sys::AIBinder736     fn as_native(&self) -> *const sys::AIBinder {
737         self.0.as_ptr()
738     }
739 
as_native_mut(&mut self) -> *mut sys::AIBinder740     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
741         self.0.as_ptr()
742     }
743 }
744