• 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, CStr, CString};
33 use std::fmt;
34 use std::mem;
35 use std::os::raw::c_char;
36 use std::os::unix::io::AsRawFd;
37 use std::ptr;
38 use std::sync::Arc;
39 
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.
44 pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
45 
46 impl fmt::Debug for SpIBinder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result47     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48         f.pad("SpIBinder")
49     }
50 }
51 
52 /// # Safety
53 ///
54 /// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
55 unsafe impl Send for SpIBinder {}
56 
57 /// # Safety
58 ///
59 /// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
60 unsafe impl Sync for SpIBinder {}
61 
62 impl 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).
from_raw(ptr: *mut sys::AIBinder) -> Option<Self>79     pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
80         ptr::NonNull::new(ptr).map(Self)
81     }
82 
83     /// 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.
as_raw(&self) -> *mut sys::AIBinder93     pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
94         self.0.as_ptr()
95     }
96 
97     /// Return true if this binder object is hosted in a different process than
98     /// the current one.
is_remote(&self) -> bool99     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.
into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>>112     pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
113         FromIBinder::try_from(self)
114     }
115 
116     /// Return the interface class of this binder object, if associated with
117     /// one.
get_class(&mut self) -> Option<InterfaceClass>118     pub fn get_class(&mut self) -> Option<InterfaceClass> {
119         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     }
129 
130     /// Creates a new weak reference to this binder object.
downgrade(&mut self) -> WpIBinder131     pub fn downgrade(&mut self) -> WpIBinder {
132         WpIBinder::new(self)
133     }
134 }
135 
interface_cast<T: FromIBinder + ?Sized>(service: Option<SpIBinder>) -> Result<Strong<T>>136 fn 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 
144 pub 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`.
new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder>154     pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
155         SpIBinder::from_raw(ptr)
156     }
157 }
158 
159 /// An object that can be associate with an [`InterfaceClass`].
160 pub 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.
associate_class(&mut self, class: InterfaceClass) -> bool169     fn associate_class(&mut self, class: InterfaceClass) -> bool;
170 }
171 
172 impl AssociateClass for SpIBinder {
associate_class(&mut self, class: InterfaceClass) -> bool173     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 
184 impl Ord for SpIBinder {
cmp(&self, other: &Self) -> Ordering185     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).
190             sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
191         };
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).
196             sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
197         };
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 
208 impl PartialOrd for SpIBinder {
partial_cmp(&self, other: &Self) -> Option<Ordering>209     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
210         Some(self.cmp(other))
211     }
212 }
213 
214 impl PartialEq for SpIBinder {
eq(&self, other: &Self) -> bool215     fn eq(&self, other: &Self) -> bool {
216         ptr::eq(self.0.as_ptr(), other.0.as_ptr())
217     }
218 }
219 
220 impl Eq for SpIBinder {}
221 
222 impl Clone for SpIBinder {
clone(&self) -> Self223     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.
228             sys::AIBinder_incStrong(self.0.as_ptr());
229         }
230         Self(self.0)
231     }
232 }
233 
234 impl Drop for SpIBinder {
235     // We hold a strong reference to the IBinder in SpIBinder and need to give up
236     // this reference on drop.
drop(&mut self)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 
246 impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
prepare_transact(&self) -> Result<Parcel>247     fn prepare_transact(&self) -> Result<Parcel> {
248         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         };
260 
261         status_result(status)?;
262 
263         unsafe {
264             // Safety: At this point, `input` is either a valid, owned `AParcel`
265             // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
266             // taking ownership of the parcel.
267             Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
268         }
269     }
270 
submit_transact( &self, code: TransactionCode, data: Parcel, flags: TransactionFlags, ) -> Result<Parcel>271     fn submit_transact(
272         &self,
273         code: TransactionCode,
274         data: Parcel,
275         flags: TransactionFlags,
276     ) -> Result<Parcel> {
277         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             //
292             // This call takes ownership of the `data` parcel pointer, and
293             // 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,
298                 &mut data.into_raw(),
299                 &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
310             // construct an owned variant.
311             Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
312         }
313     }
314 
is_binder_alive(&self) -> bool315     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 
325     #[cfg(not(android_vndk))]
set_requesting_sid(&mut self, enable: bool)326     fn set_requesting_sid(&mut self, enable: bool) {
327         unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
328     }
329 
dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>330     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 
get_extension(&mut self) -> Result<Option<SpIBinder>>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     }
376 }
377 
378 impl<T: AsNative<sys::AIBinder>> IBinder for T {
link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>379     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
384             // `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.
391             sys::AIBinder_linkToDeath(
392                 self.as_native_mut(),
393                 recipient.as_native_mut(),
394                 recipient.new_cookie(),
395             )
396         })
397     }
398 
unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>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
404             // `AIBinder_DeathRecipient`. Any value is safe to pass as the
405             // 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     }
414 
ping_binder(&mut self) -> Result<()>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     }
425 }
426 
427 impl Serialize for SpIBinder {
serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>428     fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
429         parcel.write_binder(Some(self))
430     }
431 }
432 
433 impl SerializeOption for SpIBinder {
serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()>434     fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
435         parcel.write_binder(this)
436     }
437 }
438 
439 impl SerializeArray for SpIBinder {}
440 
441 impl Deserialize for SpIBinder {
deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder>442     fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
443         parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
444     }
445 }
446 
447 impl DeserializeOption for SpIBinder {
deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>>448     fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
449         parcel.read_binder()
450     }
451 }
452 
453 impl DeserializeArray for SpIBinder {}
454 
455 /// A weak reference to a Binder remote object.
456 ///
457 /// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
458 /// is untyped; typed interface access is implemented by the AIDL compiler.
459 pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
460 
461 impl fmt::Debug for WpIBinder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result462     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
463         f.pad("WpIBinder")
464     }
465 }
466 
467 /// # Safety
468 ///
469 /// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
470 unsafe impl Send for WpIBinder {}
471 
472 /// # Safety
473 ///
474 /// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
475 unsafe impl Sync for WpIBinder {}
476 
477 impl WpIBinder {
478     /// Create a new weak reference from an object that can be converted into a
479     /// raw `AIBinder` pointer.
new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder480     fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
481         let ptr = unsafe {
482             // Safety: `SpIBinder` guarantees that `binder` always contains a
483             // valid pointer to an `AIBinder`.
484             sys::AIBinder_Weak_new(binder.as_native_mut())
485         };
486         Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
487     }
488 
489     /// Promote this weak reference to a strong reference to the binder object.
promote(&self) -> Option<SpIBinder>490     pub fn promote(&self) -> Option<SpIBinder> {
491         unsafe {
492             // Safety: `WpIBinder` always contains a valid weak reference, so we
493             // can pass this pointer to `AIBinder_Weak_promote`. Returns either
494             // null or an AIBinder owned by the caller, both of which are valid
495             // to pass to `SpIBinder::from_raw`.
496             let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
497             SpIBinder::from_raw(ptr)
498         }
499     }
500 }
501 
502 impl Clone for WpIBinder {
clone(&self) -> Self503     fn clone(&self) -> Self {
504         let ptr = unsafe {
505             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
506             // so this pointer is always safe to pass to `AIBinder_Weak_clone`
507             // (although null is also a safe value to pass to this API).
508             //
509             // We get ownership of the returned pointer, so can construct a new
510             // WpIBinder object from it.
511             sys::AIBinder_Weak_clone(self.0.as_ptr())
512         };
513         Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
514     }
515 }
516 
517 impl Ord for WpIBinder {
cmp(&self, other: &Self) -> Ordering518     fn cmp(&self, other: &Self) -> Ordering {
519         let less_than = unsafe {
520             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
521             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
522             // (null is also safe to pass to this function, but we should never
523             // do that).
524             sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr())
525         };
526         let greater_than = unsafe {
527             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
528             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
529             // (null is also safe to pass to this function, but we should never
530             // do that).
531             sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
532         };
533         if !less_than && !greater_than {
534             Ordering::Equal
535         } else if less_than {
536             Ordering::Less
537         } else {
538             Ordering::Greater
539         }
540     }
541 }
542 
543 impl PartialOrd for WpIBinder {
partial_cmp(&self, other: &Self) -> Option<Ordering>544     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
545         Some(self.cmp(other))
546     }
547 }
548 
549 impl PartialEq for WpIBinder {
eq(&self, other: &Self) -> bool550     fn eq(&self, other: &Self) -> bool {
551         self.cmp(other) == Ordering::Equal
552     }
553 }
554 
555 impl Eq for WpIBinder {}
556 
557 impl Drop for WpIBinder {
drop(&mut self)558     fn drop(&mut self) {
559         unsafe {
560             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
561             // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
562             sys::AIBinder_Weak_delete(self.0.as_ptr());
563         }
564     }
565 }
566 
567 /// Rust wrapper around DeathRecipient objects.
568 ///
569 /// The cookie in this struct represents an Arc<F> for the owned callback.
570 /// This struct owns a ref-count of it, and so does every binder that we
571 /// have been linked with.
572 ///
573 /// Dropping the `DeathRecipient` will `unlink_to_death` any binders it is
574 /// currently linked to.
575 #[repr(C)]
576 pub struct DeathRecipient {
577     recipient: *mut sys::AIBinder_DeathRecipient,
578     cookie: *mut c_void,
579     vtable: &'static DeathRecipientVtable,
580 }
581 
582 struct DeathRecipientVtable {
583     cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
584     cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
585 }
586 
587 /// # Safety
588 ///
589 /// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
590 /// to a `Fn` which is `Sync` and `Send` (the cookie field). As
591 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
592 unsafe impl Send for DeathRecipient {}
593 
594 /// # Safety
595 ///
596 /// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
597 /// to a `Fn` which is `Sync` and `Send` (the cookie field). As
598 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
599 unsafe impl Sync for DeathRecipient {}
600 
601 impl DeathRecipient {
602     /// Create a new death recipient that will call the given callback when its
603     /// associated object dies.
new<F>(callback: F) -> DeathRecipient where F: Fn() + Send + Sync + 'static,604     pub fn new<F>(callback: F) -> DeathRecipient
605     where
606         F: Fn() + Send + Sync + 'static,
607     {
608         let callback: *const F = Arc::into_raw(Arc::new(callback));
609         let recipient = unsafe {
610             // Safety: The function pointer is a valid death recipient callback.
611             //
612             // This call returns an owned `AIBinder_DeathRecipient` pointer
613             // which must be destroyed via `AIBinder_DeathRecipient_delete` when
614             // no longer needed.
615             sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
616         };
617         unsafe {
618             // Safety: The function pointer is a valid onUnlinked callback.
619             //
620             // All uses of linkToDeath in this file correctly increment the
621             // ref-count that this onUnlinked callback will decrement.
622             sys::AIBinder_DeathRecipient_setOnUnlinked(
623                 recipient,
624                 Some(Self::cookie_decr_refcount::<F>),
625             );
626         }
627         DeathRecipient {
628             recipient,
629             cookie: callback as *mut c_void,
630             vtable: &DeathRecipientVtable {
631                 cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
632                 cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
633             },
634         }
635     }
636 
637     /// Increment the ref-count for the cookie and return it.
638     ///
639     /// # Safety
640     ///
641     /// The caller must handle the returned ref-count correctly.
new_cookie(&self) -> *mut c_void642     unsafe fn new_cookie(&self) -> *mut c_void {
643         (self.vtable.cookie_incr_refcount)(self.cookie);
644 
645         // Return a raw pointer with ownership of a ref-count
646         self.cookie
647     }
648 
649     /// Get the opaque cookie that identifies this death recipient.
650     ///
651     /// This cookie will be used to link and unlink this death recipient to a
652     /// binder object and will be passed to the `binder_died` callback as an
653     /// opaque userdata pointer.
get_cookie(&self) -> *mut c_void654     fn get_cookie(&self) -> *mut c_void {
655         self.cookie
656     }
657 
658     /// Callback invoked from C++ when the binder object dies.
659     ///
660     /// # Safety
661     ///
662     /// The `cookie` parameter must be the cookie for an Arc<F> and
663     /// the caller must hold a ref-count to it.
binder_died<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,664     unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
665     where
666         F: Fn() + Send + Sync + 'static,
667     {
668         let callback = (cookie as *const F).as_ref().unwrap();
669         callback();
670     }
671 
672     /// Callback that decrements the ref-count.
673     /// This is invoked from C++ when a binder is unlinked.
674     ///
675     /// # Safety
676     ///
677     /// The `cookie` parameter must be the cookie for an Arc<F> and
678     /// the owner must give up a ref-count to it.
cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,679     unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
680     where
681         F: Fn() + Send + Sync + 'static,
682     {
683         drop(Arc::from_raw(cookie as *const F));
684     }
685 
686     /// Callback that increments the ref-count.
687     ///
688     /// # Safety
689     ///
690     /// The `cookie` parameter must be the cookie for an Arc<F> and
691     /// the owner must handle the created ref-count properly.
cookie_incr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,692     unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
693     where
694         F: Fn() + Send + Sync + 'static,
695     {
696         let arc = mem::ManuallyDrop::new(Arc::from_raw(cookie as *const F));
697         mem::forget(Arc::clone(&arc));
698     }
699 }
700 
701 /// # Safety
702 ///
703 /// A `DeathRecipient` is always constructed with a valid raw pointer to an
704 /// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
705 /// pointer.
706 unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
as_native(&self) -> *const sys::AIBinder_DeathRecipient707     fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
708         self.recipient
709     }
710 
as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient711     fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
712         self.recipient
713     }
714 }
715 
716 impl Drop for DeathRecipient {
drop(&mut self)717     fn drop(&mut self) {
718         unsafe {
719             // Safety: `self.recipient` is always a valid, owned
720             // `AIBinder_DeathRecipient` pointer returned by
721             // `AIBinder_DeathRecipient_new` when `self` was created. This
722             // delete method can only be called once when `self` is dropped.
723             sys::AIBinder_DeathRecipient_delete(self.recipient);
724 
725             // Safety: We own a ref-count to the cookie, and so does every
726             // linked binder. This call gives up our ref-count. The linked
727             // binders should already have given up their ref-count, or should
728             // do so shortly.
729             (self.vtable.cookie_decr_refcount)(self.cookie)
730         }
731     }
732 }
733 
734 /// Generic interface to remote binder objects.
735 ///
736 /// Corresponds to the C++ `BpInterface` class.
737 pub trait Proxy: Sized + Interface {
738     /// The Binder interface descriptor string.
739     ///
740     /// This string is a unique identifier for a Binder interface, and should be
741     /// the same between all implementations of that interface.
get_descriptor() -> &'static str742     fn get_descriptor() -> &'static str;
743 
744     /// Create a new interface from the given proxy, if it matches the expected
745     /// type of this interface.
from_binder(binder: SpIBinder) -> Result<Self>746     fn from_binder(binder: SpIBinder) -> Result<Self>;
747 }
748 
749 /// # Safety
750 ///
751 /// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
752 /// invocation of `IBinder` methods directly from `Interface` objects. It shares
753 /// the same safety as the implementation for `SpIBinder`.
754 unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
as_native(&self) -> *const sys::AIBinder755     fn as_native(&self) -> *const sys::AIBinder {
756         self.as_binder().as_native()
757     }
758 
as_native_mut(&mut self) -> *mut sys::AIBinder759     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
760         self.as_binder().as_native_mut()
761     }
762 }
763 
764 /// Retrieve an existing service, blocking for a few seconds if it doesn't yet
765 /// exist.
get_service(name: &str) -> Option<SpIBinder>766 pub fn get_service(name: &str) -> Option<SpIBinder> {
767     let name = CString::new(name).ok()?;
768     unsafe {
769         // Safety: `AServiceManager_getService` returns either a null pointer or
770         // a valid pointer to an owned `AIBinder`. Either of these values is
771         // safe to pass to `SpIBinder::from_raw`.
772         SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
773     }
774 }
775 
776 /// Retrieve an existing service, or start it if it is configured as a dynamic
777 /// service and isn't yet started.
wait_for_service(name: &str) -> Option<SpIBinder>778 pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
779     let name = CString::new(name).ok()?;
780     unsafe {
781         // Safety: `AServiceManager_waitforService` returns either a null
782         // pointer or a valid pointer to an owned `AIBinder`. Either of these
783         // values is safe to pass to `SpIBinder::from_raw`.
784         SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
785     }
786 }
787 
788 /// Retrieve an existing service for a particular interface, blocking for a few
789 /// seconds if it doesn't yet exist.
get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>>790 pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
791     interface_cast(get_service(name))
792 }
793 
794 /// Retrieve an existing service for a particular interface, or start it if it
795 /// is configured as a dynamic service and isn't yet started.
wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>>796 pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
797     interface_cast(wait_for_service(name))
798 }
799 
800 /// Check if a service is declared (e.g. in a VINTF manifest)
is_declared(interface: &str) -> Result<bool>801 pub fn is_declared(interface: &str) -> Result<bool> {
802     let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
803 
804     unsafe {
805         // Safety: `interface` is a valid null-terminated C-style string and is
806         // only borrowed for the lifetime of the call. The `interface` local
807         // outlives this call as it lives for the function scope.
808         Ok(sys::AServiceManager_isDeclared(interface.as_ptr()))
809     }
810 }
811 
812 /// Retrieve all declared instances for a particular interface
813 ///
814 /// For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo'
815 /// is passed here, then ["foo"] would be returned.
get_declared_instances(interface: &str) -> Result<Vec<String>>816 pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
817     unsafe extern "C" fn callback(instance: *const c_char, opaque: *mut c_void) {
818         // Safety: opaque was a mutable pointer created below from a Vec of
819         // CString, and outlives this callback. The null handling here is just
820         // to avoid the possibility of unwinding across C code if this crate is
821         // ever compiled with panic=unwind.
822         if let Some(instances) = opaque.cast::<Vec<CString>>().as_mut() {
823             // Safety: instance is a valid null-terminated C string with a
824             // lifetime at least as long as this function, and we immediately
825             // copy it into an owned CString.
826             instances.push(CStr::from_ptr(instance).to_owned());
827         } else {
828             eprintln!("Opaque pointer was null in get_declared_instances callback!");
829         }
830     }
831 
832     let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
833     let mut instances: Vec<CString> = vec![];
834     unsafe {
835         // Safety: `interface` and `instances` are borrowed for the length of
836         // this call and both outlive the call. `interface` is guaranteed to be
837         // a valid null-terminated C-style string.
838         sys::AServiceManager_forEachDeclaredInstance(
839             interface.as_ptr(),
840             &mut instances as *mut _ as *mut c_void,
841             Some(callback),
842         );
843     }
844 
845     instances
846         .into_iter()
847         .map(CString::into_string)
848         .collect::<std::result::Result<Vec<String>, _>>()
849         .map_err(|e| {
850             eprintln!("An interface instance name was not a valid UTF-8 string: {}", e);
851             StatusCode::BAD_VALUE
852         })
853 }
854 
855 /// # Safety
856 ///
857 /// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
858 /// `AIBinder`, so we can trivially extract this pointer here.
859 unsafe impl AsNative<sys::AIBinder> for SpIBinder {
as_native(&self) -> *const sys::AIBinder860     fn as_native(&self) -> *const sys::AIBinder {
861         self.0.as_ptr()
862     }
863 
as_native_mut(&mut self) -> *mut sys::AIBinder864     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
865         self.0.as_ptr()
866     }
867 }
868