• 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     Parcel, BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
26 };
27 use crate::sys;
28 
29 use std::cmp::Ordering;
30 use std::convert::TryInto;
31 use std::ffi::{c_void, CStr, CString};
32 use std::fmt;
33 use std::mem;
34 use std::os::raw::c_char;
35 use std::os::unix::io::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
52 ///
53 /// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
54 unsafe impl Send for SpIBinder {}
55 
56 /// # Safety
57 ///
58 /// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
59 unsafe impl Sync for SpIBinder {}
60 
61 impl SpIBinder {
62     /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
63     ///
64     /// # Safety
65     ///
66     /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
67     /// to an `AIBinder`.
68     ///
69     /// In the non-null case, this method conceptually takes ownership of a strong
70     /// reference to the object, so `AIBinder_incStrong` must have been called
71     /// on the pointer before passing it to this constructor. This is generally
72     /// done by Binder NDK methods that return an `AIBinder`, but care should be
73     /// taken to ensure this invariant.
74     ///
75     /// All `SpIBinder` objects that are constructed will hold a valid pointer
76     /// to an `AIBinder`, which will remain valid for the entire lifetime of the
77     /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
from_raw(ptr: *mut sys::AIBinder) -> Option<Self>78     pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
79         ptr::NonNull::new(ptr).map(Self)
80     }
81 
82     /// Extract a raw `AIBinder` pointer from this wrapper.
83     ///
84     /// This method should _only_ be used for testing. Do not try to use the NDK
85     /// interface directly for anything else.
86     ///
87     /// # Safety
88     ///
89     /// The resulting pointer is valid only as long as the SpIBinder is alive.
90     /// The SpIBinder object retains ownership of the AIBinder and the caller
91     /// should not attempt to free the returned pointer.
as_raw(&self) -> *mut sys::AIBinder92     pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
93         self.0.as_ptr()
94     }
95 
96     /// Return true if this binder object is hosted in a different process than
97     /// the current one.
is_remote(&self) -> bool98     pub fn is_remote(&self) -> bool {
99         unsafe {
100             // Safety: `SpIBinder` guarantees that it always contains a valid
101             // `AIBinder` pointer.
102             sys::AIBinder_isRemote(self.as_native())
103         }
104     }
105 
106     /// Try to convert this Binder object into a trait object for the given
107     /// Binder interface.
108     ///
109     /// If this object does not implement the expected interface, the error
110     /// `StatusCode::BAD_TYPE` is returned.
into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>>111     pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
112         FromIBinder::try_from(self)
113     }
114 
115     /// Return the interface class of this binder object, if associated with
116     /// one.
get_class(&mut self) -> Option<InterfaceClass>117     pub fn get_class(&mut self) -> Option<InterfaceClass> {
118         unsafe {
119             // Safety: `SpIBinder` guarantees that it always contains a valid
120             // `AIBinder` pointer. `AIBinder_getClass` returns either a null
121             // pointer or a valid pointer to an `AIBinder_Class`. After mapping
122             // null to None, we can safely construct an `InterfaceClass` if the
123             // pointer was non-null.
124             let class = sys::AIBinder_getClass(self.as_native_mut());
125             class.as_ref().map(|p| InterfaceClass::from_ptr(p))
126         }
127     }
128 
129     /// Creates a new weak reference to this binder object.
downgrade(&mut self) -> WpIBinder130     pub fn downgrade(&mut self) -> WpIBinder {
131         WpIBinder::new(self)
132     }
133 }
134 
135 pub mod unstable_api {
136     use super::{sys, SpIBinder};
137 
138     /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
139     /// needed to bridge RPC binder, which doesn't have Rust API yet.
140     /// TODO(b/184872979): remove once the Rust API is created.
141     ///
142     /// # Safety
143     ///
144     /// See `SpIBinder::from_raw`.
new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder>145     pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
146         SpIBinder::from_raw(ptr)
147     }
148 }
149 
150 /// An object that can be associate with an [`InterfaceClass`].
151 pub trait AssociateClass {
152     /// Check if this object is a valid object for the given interface class
153     /// `I`.
154     ///
155     /// Returns `Some(self)` if this is a valid instance of the interface, and
156     /// `None` otherwise.
157     ///
158     /// Classes constructed by `InterfaceClass` are unique per type, so
159     /// repeatedly calling this method for the same `InterfaceClass` is allowed.
associate_class(&mut self, class: InterfaceClass) -> bool160     fn associate_class(&mut self, class: InterfaceClass) -> bool;
161 }
162 
163 impl AssociateClass for SpIBinder {
associate_class(&mut self, class: InterfaceClass) -> bool164     fn associate_class(&mut self, class: InterfaceClass) -> bool {
165         unsafe {
166             // Safety: `SpIBinder` guarantees that it always contains a valid
167             // `AIBinder` pointer. An `InterfaceClass` can always be converted
168             // into a valid `AIBinder_Class` pointer, so these parameters are
169             // always safe.
170             sys::AIBinder_associateClass(self.as_native_mut(), class.into())
171         }
172     }
173 }
174 
175 impl Ord for SpIBinder {
cmp(&self, other: &Self) -> Ordering176     fn cmp(&self, other: &Self) -> Ordering {
177         let less_than = unsafe {
178             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
179             // this pointer is always safe to pass to `AIBinder_lt` (null is
180             // also safe to pass to this function, but we should never do that).
181             sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
182         };
183         let greater_than = unsafe {
184             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
185             // this pointer is always safe to pass to `AIBinder_lt` (null is
186             // also safe to pass to this function, but we should never do that).
187             sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
188         };
189         if !less_than && !greater_than {
190             Ordering::Equal
191         } else if less_than {
192             Ordering::Less
193         } else {
194             Ordering::Greater
195         }
196     }
197 }
198 
199 impl PartialOrd for SpIBinder {
partial_cmp(&self, other: &Self) -> Option<Ordering>200     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
201         Some(self.cmp(other))
202     }
203 }
204 
205 impl PartialEq for SpIBinder {
eq(&self, other: &Self) -> bool206     fn eq(&self, other: &Self) -> bool {
207         ptr::eq(self.0.as_ptr(), other.0.as_ptr())
208     }
209 }
210 
211 impl Eq for SpIBinder {}
212 
213 impl Clone for SpIBinder {
clone(&self) -> Self214     fn clone(&self) -> Self {
215         unsafe {
216             // Safety: Cloning a strong reference must increment the reference
217             // count. We are guaranteed by the `SpIBinder` constructor
218             // invariants that `self.0` is always a valid `AIBinder` pointer.
219             sys::AIBinder_incStrong(self.0.as_ptr());
220         }
221         Self(self.0)
222     }
223 }
224 
225 impl Drop for SpIBinder {
226     // We hold a strong reference to the IBinder in SpIBinder and need to give up
227     // this reference on drop.
drop(&mut self)228     fn drop(&mut self) {
229         unsafe {
230             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
231             // know this pointer is safe to pass to `AIBinder_decStrong` here.
232             sys::AIBinder_decStrong(self.as_native_mut());
233         }
234     }
235 }
236 
237 impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
prepare_transact(&self) -> Result<Parcel>238     fn prepare_transact(&self) -> Result<Parcel> {
239         let mut input = ptr::null_mut();
240         let status = unsafe {
241             // Safety: `SpIBinder` guarantees that `self` always contains a
242             // valid pointer to an `AIBinder`. It is safe to cast from an
243             // immutable pointer to a mutable pointer here, because
244             // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
245             // methods but the parameter is unfortunately not marked as const.
246             //
247             // After the call, input will be either a valid, owned `AParcel`
248             // pointer, or null.
249             sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
250         };
251 
252         status_result(status)?;
253 
254         unsafe {
255             // Safety: At this point, `input` is either a valid, owned `AParcel`
256             // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
257             // taking ownership of the parcel.
258             Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
259         }
260     }
261 
submit_transact( &self, code: TransactionCode, data: Parcel, flags: TransactionFlags, ) -> Result<Parcel>262     fn submit_transact(
263         &self,
264         code: TransactionCode,
265         data: Parcel,
266         flags: TransactionFlags,
267     ) -> Result<Parcel> {
268         let mut reply = ptr::null_mut();
269         let status = unsafe {
270             // Safety: `SpIBinder` guarantees that `self` always contains a
271             // valid pointer to an `AIBinder`. Although `IBinder::transact` is
272             // not a const method, it is still safe to cast our immutable
273             // pointer to mutable for the call. First, `IBinder::transact` is
274             // thread-safe, so concurrency is not an issue. The only way that
275             // `transact` can affect any visible, mutable state in the current
276             // process is by calling `onTransact` for a local service. However,
277             // in order for transactions to be thread-safe, this method must
278             // dynamically lock its data before modifying it. We enforce this
279             // property in Rust by requiring `Sync` for remotable objects and
280             // only providing `on_transact` with an immutable reference to
281             // `self`.
282             //
283             // This call takes ownership of the `data` parcel pointer, and
284             // passes ownership of the `reply` out parameter to its caller. It
285             // does not affect ownership of the `binder` parameter.
286             sys::AIBinder_transact(
287                 self.as_native() as *mut sys::AIBinder,
288                 code,
289                 &mut data.into_raw(),
290                 &mut reply,
291                 flags,
292             )
293         };
294         status_result(status)?;
295 
296         unsafe {
297             // Safety: `reply` is either a valid `AParcel` pointer or null
298             // after the call to `AIBinder_transact` above, so we can
299             // construct a `Parcel` out of it. `AIBinder_transact` passes
300             // ownership of the `reply` parcel to Rust, so we need to
301             // construct an owned variant.
302             Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
303         }
304     }
305 
is_binder_alive(&self) -> bool306     fn is_binder_alive(&self) -> bool {
307         unsafe {
308             // Safety: `SpIBinder` guarantees that `self` always contains a
309             // valid pointer to an `AIBinder`.
310             //
311             // This call does not affect ownership of its pointer parameter.
312             sys::AIBinder_isAlive(self.as_native())
313         }
314     }
315 
316     #[cfg(not(android_vndk))]
set_requesting_sid(&mut self, enable: bool)317     fn set_requesting_sid(&mut self, enable: bool) {
318         unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
319     }
320 
dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>321     fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
322         let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
323         let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
324         let status = unsafe {
325             // Safety: `SpIBinder` guarantees that `self` always contains a
326             // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
327             // file descriptor parameter is always be a valid open file. The
328             // `args` pointer parameter is a valid pointer to an array of C
329             // strings that will outlive the call since `args` lives for the
330             // whole function scope.
331             //
332             // This call does not affect ownership of its binder pointer
333             // parameter and does not take ownership of the file or args array
334             // parameters.
335             sys::AIBinder_dump(
336                 self.as_native_mut(),
337                 fp.as_raw_fd(),
338                 arg_ptrs.as_mut_ptr(),
339                 arg_ptrs.len().try_into().unwrap(),
340             )
341         };
342         status_result(status)
343     }
344 
get_extension(&mut self) -> Result<Option<SpIBinder>>345     fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
346         let mut out = ptr::null_mut();
347         let status = unsafe {
348             // Safety: `SpIBinder` guarantees that `self` always contains a
349             // valid pointer to an `AIBinder`. After this call, the `out`
350             // parameter will be either null, or a valid pointer to an
351             // `AIBinder`.
352             //
353             // This call passes ownership of the out pointer to its caller
354             // (assuming it is set to a non-null value).
355             sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
356         };
357         let ibinder = unsafe {
358             // Safety: The call above guarantees that `out` is either null or a
359             // valid, owned pointer to an `AIBinder`, both of which are safe to
360             // pass to `SpIBinder::from_raw`.
361             SpIBinder::from_raw(out)
362         };
363 
364         status_result(status)?;
365         Ok(ibinder)
366     }
367 }
368 
369 impl<T: AsNative<sys::AIBinder>> IBinder for T {
link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>370     fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
371         status_result(unsafe {
372             // Safety: `SpIBinder` guarantees that `self` always contains a
373             // valid pointer to an `AIBinder`. `recipient` can always be
374             // converted into a valid pointer to an
375             // `AIBinder_DeathRecipient`.
376             //
377             // The cookie is also the correct pointer, and by calling new_cookie,
378             // we have created a new ref-count to the cookie, which linkToDeath
379             // takes ownership of. Once the DeathRecipient is unlinked for any
380             // reason (including if this call fails), the onUnlinked callback
381             // will consume that ref-count.
382             sys::AIBinder_linkToDeath(
383                 self.as_native_mut(),
384                 recipient.as_native_mut(),
385                 recipient.new_cookie(),
386             )
387         })
388     }
389 
unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>390     fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
391         status_result(unsafe {
392             // Safety: `SpIBinder` guarantees that `self` always contains a
393             // valid pointer to an `AIBinder`. `recipient` can always be
394             // converted into a valid pointer to an
395             // `AIBinder_DeathRecipient`. Any value is safe to pass as the
396             // cookie, although we depend on this value being set by
397             // `get_cookie` when the death recipient callback is called.
398             sys::AIBinder_unlinkToDeath(
399                 self.as_native_mut(),
400                 recipient.as_native_mut(),
401                 recipient.get_cookie(),
402             )
403         })
404     }
405 
ping_binder(&mut self) -> Result<()>406     fn ping_binder(&mut self) -> Result<()> {
407         let status = unsafe {
408             // Safety: `SpIBinder` guarantees that `self` always contains a
409             // valid pointer to an `AIBinder`.
410             //
411             // This call does not affect ownership of its pointer parameter.
412             sys::AIBinder_ping(self.as_native_mut())
413         };
414         status_result(status)
415     }
416 }
417 
418 impl Serialize for SpIBinder {
serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>419     fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
420         parcel.write_binder(Some(self))
421     }
422 }
423 
424 impl SerializeOption for SpIBinder {
serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()>425     fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
426         parcel.write_binder(this)
427     }
428 }
429 
430 impl SerializeArray for SpIBinder {}
431 
432 impl Deserialize for SpIBinder {
deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder>433     fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
434         parcel
435             .read_binder()
436             .transpose()
437             .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
438     }
439 }
440 
441 impl DeserializeOption for SpIBinder {
deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>>442     fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
443         parcel.read_binder()
444     }
445 }
446 
447 impl DeserializeArray for SpIBinder {}
448 
449 /// A weak reference to a Binder remote object.
450 ///
451 /// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
452 /// is untyped; typed interface access is implemented by the AIDL compiler.
453 pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
454 
455 impl fmt::Debug for WpIBinder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result456     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
457         f.pad("WpIBinder")
458     }
459 }
460 
461 /// # Safety
462 ///
463 /// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
464 unsafe impl Send for WpIBinder {}
465 
466 /// # Safety
467 ///
468 /// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
469 unsafe impl Sync for WpIBinder {}
470 
471 impl WpIBinder {
472     /// Create a new weak reference from an object that can be converted into a
473     /// raw `AIBinder` pointer.
new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder474     fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
475         let ptr = unsafe {
476             // Safety: `SpIBinder` guarantees that `binder` always contains a
477             // valid pointer to an `AIBinder`.
478             sys::AIBinder_Weak_new(binder.as_native_mut())
479         };
480         Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
481     }
482 
483     /// Promote this weak reference to a strong reference to the binder object.
promote(&self) -> Option<SpIBinder>484     pub fn promote(&self) -> Option<SpIBinder> {
485         unsafe {
486             // Safety: `WpIBinder` always contains a valid weak reference, so we
487             // can pass this pointer to `AIBinder_Weak_promote`. Returns either
488             // null or an AIBinder owned by the caller, both of which are valid
489             // to pass to `SpIBinder::from_raw`.
490             let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
491             SpIBinder::from_raw(ptr)
492         }
493     }
494 }
495 
496 impl Clone for WpIBinder {
clone(&self) -> Self497     fn clone(&self) -> Self {
498         let ptr = unsafe {
499             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
500             // so this pointer is always safe to pass to `AIBinder_Weak_clone`
501             // (although null is also a safe value to pass to this API).
502             //
503             // We get ownership of the returned pointer, so can construct a new
504             // WpIBinder object from it.
505             sys::AIBinder_Weak_clone(self.0.as_ptr())
506         };
507         Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
508     }
509 }
510 
511 impl Ord for WpIBinder {
cmp(&self, other: &Self) -> Ordering512     fn cmp(&self, other: &Self) -> Ordering {
513         let less_than = unsafe {
514             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
515             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
516             // (null is also safe to pass to this function, but we should never
517             // do that).
518             sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr())
519         };
520         let greater_than = unsafe {
521             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
522             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
523             // (null is also safe to pass to this function, but we should never
524             // do that).
525             sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
526         };
527         if !less_than && !greater_than {
528             Ordering::Equal
529         } else if less_than {
530             Ordering::Less
531         } else {
532             Ordering::Greater
533         }
534     }
535 }
536 
537 impl PartialOrd for WpIBinder {
partial_cmp(&self, other: &Self) -> Option<Ordering>538     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
539         Some(self.cmp(other))
540     }
541 }
542 
543 impl PartialEq for WpIBinder {
eq(&self, other: &Self) -> bool544     fn eq(&self, other: &Self) -> bool {
545         self.cmp(other) == Ordering::Equal
546     }
547 }
548 
549 impl Eq for WpIBinder {}
550 
551 impl Drop for WpIBinder {
drop(&mut self)552     fn drop(&mut self) {
553         unsafe {
554             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
555             // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
556             sys::AIBinder_Weak_delete(self.0.as_ptr());
557         }
558     }
559 }
560 
561 /// Rust wrapper around DeathRecipient objects.
562 ///
563 /// The cookie in this struct represents an Arc<F> for the owned callback.
564 /// This struct owns a ref-count of it, and so does every binder that we
565 /// have been linked with.
566 #[repr(C)]
567 pub struct DeathRecipient {
568     recipient: *mut sys::AIBinder_DeathRecipient,
569     cookie: *mut c_void,
570     vtable: &'static DeathRecipientVtable,
571 }
572 
573 struct DeathRecipientVtable {
574     cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
575     cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
576 }
577 
578 /// # Safety
579 ///
580 /// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
581 /// to a `Fn` which is `Sync` and `Send` (the cookie field). As
582 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
583 unsafe impl Send for DeathRecipient {}
584 
585 /// # Safety
586 ///
587 /// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
588 /// to a `Fn` which is `Sync` and `Send` (the cookie field). As
589 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
590 unsafe impl Sync for DeathRecipient {}
591 
592 impl DeathRecipient {
593     /// Create a new death recipient that will call the given callback when its
594     /// associated object dies.
new<F>(callback: F) -> DeathRecipient where F: Fn() + Send + Sync + 'static,595     pub fn new<F>(callback: F) -> DeathRecipient
596     where
597         F: Fn() + Send + Sync + 'static,
598     {
599         let callback: *const F = Arc::into_raw(Arc::new(callback));
600         let recipient = unsafe {
601             // Safety: The function pointer is a valid death recipient callback.
602             //
603             // This call returns an owned `AIBinder_DeathRecipient` pointer
604             // which must be destroyed via `AIBinder_DeathRecipient_delete` when
605             // no longer needed.
606             sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
607         };
608         unsafe {
609             // Safety: The function pointer is a valid onUnlinked callback.
610             //
611             // All uses of linkToDeath in this file correctly increment the
612             // ref-count that this onUnlinked callback will decrement.
613             sys::AIBinder_DeathRecipient_setOnUnlinked(recipient, Some(Self::cookie_decr_refcount::<F>));
614         }
615         DeathRecipient {
616             recipient,
617             cookie: callback as *mut c_void,
618             vtable: &DeathRecipientVtable {
619                 cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
620                 cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
621             },
622         }
623     }
624 
625     /// Increment the ref-count for the cookie and return it.
626     ///
627     /// # Safety
628     ///
629     /// The caller must handle the returned ref-count correctly.
new_cookie(&self) -> *mut c_void630     unsafe fn new_cookie(&self) -> *mut c_void {
631         (self.vtable.cookie_incr_refcount)(self.cookie);
632 
633         // Return a raw pointer with ownership of a ref-count
634         self.cookie
635     }
636 
637     /// Get the opaque cookie that identifies this death recipient.
638     ///
639     /// This cookie will be used to link and unlink this death recipient to a
640     /// binder object and will be passed to the `binder_died` callback as an
641     /// opaque userdata pointer.
get_cookie(&self) -> *mut c_void642     fn get_cookie(&self) -> *mut c_void {
643         self.cookie
644     }
645 
646     /// Callback invoked from C++ when the binder object dies.
647     ///
648     /// # Safety
649     ///
650     /// The `cookie` parameter must be the cookie for an Arc<F> and
651     /// the caller must hold a ref-count to it.
binder_died<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,652     unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
653     where
654         F: Fn() + Send + Sync + 'static,
655     {
656         let callback = (cookie as *const F).as_ref().unwrap();
657         callback();
658     }
659 
660     /// Callback that decrements the ref-count.
661     /// This is invoked from C++ when a binder is unlinked.
662     ///
663     /// # Safety
664     ///
665     /// The `cookie` parameter must be the cookie for an Arc<F> and
666     /// the owner must give up a ref-count to it.
cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,667     unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
668     where
669         F: Fn() + Send + Sync + 'static,
670     {
671         drop(Arc::from_raw(cookie as *const F));
672     }
673 
674     /// Callback that increments the ref-count.
675     ///
676     /// # Safety
677     ///
678     /// The `cookie` parameter must be the cookie for an Arc<F> and
679     /// the owner must handle the created ref-count properly.
cookie_incr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,680     unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
681     where
682         F: Fn() + Send + Sync + 'static,
683     {
684         let arc = mem::ManuallyDrop::new(Arc::from_raw(cookie as *const F));
685         mem::forget(Arc::clone(&arc));
686     }
687 }
688 
689 /// # Safety
690 ///
691 /// A `DeathRecipient` is always constructed with a valid raw pointer to an
692 /// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
693 /// pointer.
694 unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
as_native(&self) -> *const sys::AIBinder_DeathRecipient695     fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
696         self.recipient
697     }
698 
as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient699     fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
700         self.recipient
701     }
702 }
703 
704 impl Drop for DeathRecipient {
drop(&mut self)705     fn drop(&mut self) {
706         unsafe {
707             // Safety: `self.recipient` is always a valid, owned
708             // `AIBinder_DeathRecipient` pointer returned by
709             // `AIBinder_DeathRecipient_new` when `self` was created. This
710             // delete method can only be called once when `self` is dropped.
711             sys::AIBinder_DeathRecipient_delete(self.recipient);
712 
713             // Safety: We own a ref-count to the cookie, and so does every
714             // linked binder. This call gives up our ref-count. The linked
715             // binders should already have given up their ref-count, or should
716             // do so shortly.
717             (self.vtable.cookie_decr_refcount)(self.cookie)
718         }
719     }
720 }
721 
722 /// Generic interface to remote binder objects.
723 ///
724 /// Corresponds to the C++ `BpInterface` class.
725 pub trait Proxy: Sized + Interface {
726     /// The Binder interface descriptor string.
727     ///
728     /// This string is a unique identifier for a Binder interface, and should be
729     /// the same between all implementations of that interface.
get_descriptor() -> &'static str730     fn get_descriptor() -> &'static str;
731 
732     /// Create a new interface from the given proxy, if it matches the expected
733     /// type of this interface.
from_binder(binder: SpIBinder) -> Result<Self>734     fn from_binder(binder: SpIBinder) -> Result<Self>;
735 }
736 
737 /// # Safety
738 ///
739 /// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
740 /// invocation of `IBinder` methods directly from `Interface` objects. It shares
741 /// the same safety as the implementation for `SpIBinder`.
742 unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
as_native(&self) -> *const sys::AIBinder743     fn as_native(&self) -> *const sys::AIBinder {
744         self.as_binder().as_native()
745     }
746 
as_native_mut(&mut self) -> *mut sys::AIBinder747     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
748         self.as_binder().as_native_mut()
749     }
750 }
751 
752 /// Retrieve an existing service, blocking for a few seconds if it doesn't yet
753 /// exist.
get_service(name: &str) -> Option<SpIBinder>754 pub fn get_service(name: &str) -> Option<SpIBinder> {
755     let name = CString::new(name).ok()?;
756     unsafe {
757         // Safety: `AServiceManager_getService` returns either a null pointer or
758         // a valid pointer to an owned `AIBinder`. Either of these values is
759         // safe to pass to `SpIBinder::from_raw`.
760         SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
761     }
762 }
763 
764 /// Retrieve an existing service, or start it if it is configured as a dynamic
765 /// service and isn't yet started.
wait_for_service(name: &str) -> Option<SpIBinder>766 pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
767     let name = CString::new(name).ok()?;
768     unsafe {
769         // Safety: `AServiceManager_waitforService` returns either a null
770         // pointer or a valid pointer to an owned `AIBinder`. Either of these
771         // values is safe to pass to `SpIBinder::from_raw`.
772         SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
773     }
774 }
775 
776 /// Retrieve an existing service for a particular interface, blocking for a few
777 /// seconds if it doesn't yet exist.
get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>>778 pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
779     let service = get_service(name);
780     match service {
781         Some(service) => FromIBinder::try_from(service),
782         None => Err(StatusCode::NAME_NOT_FOUND),
783     }
784 }
785 
786 /// Retrieve an existing service for a particular interface, or start it if it
787 /// is configured as a dynamic service and isn't yet started.
wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>>788 pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
789     let service = wait_for_service(name);
790     match service {
791         Some(service) => FromIBinder::try_from(service),
792         None => Err(StatusCode::NAME_NOT_FOUND),
793     }
794 }
795 
796 /// Check if a service is declared (e.g. in a VINTF manifest)
is_declared(interface: &str) -> Result<bool>797 pub fn is_declared(interface: &str) -> Result<bool> {
798     let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
799 
800     unsafe {
801         // Safety: `interface` is a valid null-terminated C-style string and is
802         // only borrowed for the lifetime of the call. The `interface` local
803         // outlives this call as it lives for the function scope.
804         Ok(sys::AServiceManager_isDeclared(interface.as_ptr()))
805     }
806 }
807 
808 /// Retrieve all declared instances for a particular interface
809 ///
810 /// For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo'
811 /// is passed here, then ["foo"] would be returned.
get_declared_instances(interface: &str) -> Result<Vec<String>>812 pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
813     unsafe extern "C" fn callback(instance: *const c_char, opaque: *mut c_void) {
814         // Safety: opaque was a mutable pointer created below from a Vec of
815         // CString, and outlives this callback. The null handling here is just
816         // to avoid the possibility of unwinding across C code if this crate is
817         // ever compiled with panic=unwind.
818         if let Some(instances) = opaque.cast::<Vec<CString>>().as_mut() {
819             // Safety: instance is a valid null-terminated C string with a
820             // lifetime at least as long as this function, and we immediately
821             // copy it into an owned CString.
822             instances.push(CStr::from_ptr(instance).to_owned());
823         } else {
824             eprintln!("Opaque pointer was null in get_declared_instances callback!");
825         }
826     }
827 
828     let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
829     let mut instances: Vec<CString> = vec![];
830     unsafe {
831         // Safety: `interface` and `instances` are borrowed for the length of
832         // this call and both outlive the call. `interface` is guaranteed to be
833         // a valid null-terminated C-style string.
834         sys::AServiceManager_forEachDeclaredInstance(
835             interface.as_ptr(),
836             &mut instances as *mut _ as *mut c_void,
837             Some(callback),
838         );
839     }
840 
841     instances
842         .into_iter()
843         .map(CString::into_string)
844         .collect::<std::result::Result<Vec<String>, _>>()
845         .map_err(|e| {
846             eprintln!("An interface instance name was not a valid UTF-8 string: {}", e);
847             StatusCode::BAD_VALUE
848         })
849 }
850 
851 /// # Safety
852 ///
853 /// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
854 /// `AIBinder`, so we can trivially extract this pointer here.
855 unsafe impl AsNative<sys::AIBinder> for SpIBinder {
as_native(&self) -> *const sys::AIBinder856     fn as_native(&self) -> *const sys::AIBinder {
857         self.0.as_ptr()
858     }
859 
as_native_mut(&mut self) -> *mut sys::AIBinder860     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
861         self.0.as_ptr()
862     }
863 }
864