binder/
proxy.rs

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
19use crate::binder::{
20    AsNative, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Strong,
21    TransactionCode, TransactionFlags,
22};
23use crate::error::{status_result, Result, StatusCode};
24use crate::parcel::{
25    BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize,
26    SerializeArray, SerializeOption,
27};
28use crate::sys;
29
30use std::cmp::Ordering;
31use std::convert::TryInto;
32use std::ffi::{c_void, CString};
33use std::fmt;
34use std::mem;
35use std::os::fd::AsRawFd;
36use std::ptr;
37use 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.
43pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
44
45impl fmt::Debug for SpIBinder {
46    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.
53unsafe impl Send for SpIBinder {}
54
55/// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is
56/// thread-safe.
57unsafe impl Sync for SpIBinder {}
58
59impl 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).
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.
90    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.
96    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.
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.
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.
126    pub fn downgrade(&mut self) -> WpIBinder {
127        WpIBinder::new(self)
128    }
129}
130
131pub 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`.
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`].
148pub 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.
157    fn associate_class(&mut self, class: InterfaceClass) -> bool;
158}
159
160impl AssociateClass for SpIBinder {
161    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
170impl Ord for SpIBinder {
171    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
190impl PartialOrd for SpIBinder {
191    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
192        Some(self.cmp(other))
193    }
194}
195
196impl PartialEq for SpIBinder {
197    fn eq(&self, other: &Self) -> bool {
198        self.cmp(other) == Ordering::Equal
199    }
200}
201
202impl Eq for SpIBinder {}
203
204impl Clone for SpIBinder {
205    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
216impl Drop for SpIBinder {
217    // We hold a strong reference to the IBinder in SpIBinder and need to give up
218    // this reference on drop.
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
228impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
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
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
293    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(any(android_vndk, android_ndk)))]
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
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
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
354impl<T: AsNative<sys::AIBinder>> IBinder for T {
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
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
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
401impl Serialize for SpIBinder {
402    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
403        parcel.write_binder(Some(self))
404    }
405}
406
407impl SerializeOption for SpIBinder {
408    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
409        parcel.write_binder(this)
410    }
411}
412
413impl SerializeArray for SpIBinder {}
414
415impl Deserialize for SpIBinder {
416    type UninitType = Option<Self>;
417    fn uninit() -> Self::UninitType {
418        Self::UninitType::default()
419    }
420    fn from_init(value: Self) -> Self::UninitType {
421        Some(value)
422    }
423
424    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
425        parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
426    }
427}
428
429impl DeserializeOption for SpIBinder {
430    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
431        parcel.read_binder()
432    }
433}
434
435impl 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.
441pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
442
443impl fmt::Debug for WpIBinder {
444    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.
451unsafe impl Send for WpIBinder {}
452
453/// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is
454/// thread-safe.
455unsafe impl Sync for WpIBinder {}
456
457impl WpIBinder {
458    /// Create a new weak reference from an object that can be converted into a
459    /// raw `AIBinder` pointer.
460    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.
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
480impl Clone for WpIBinder {
481    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
493impl Ord for WpIBinder {
494    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
513impl PartialOrd for WpIBinder {
514    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
515        Some(self.cmp(other))
516    }
517}
518
519impl PartialEq for WpIBinder {
520    fn eq(&self, other: &Self) -> bool {
521        self.cmp(other) == Ordering::Equal
522    }
523}
524
525impl Eq for WpIBinder {}
526
527impl Drop for WpIBinder {
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)]
546pub struct DeathRecipient {
547    recipient: *mut sys::AIBinder_DeathRecipient,
548    cookie: *mut c_void,
549    vtable: &'static DeathRecipientVtable,
550}
551
552struct 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.
560unsafe 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.
565unsafe impl Sync for DeathRecipient {}
566
567impl DeathRecipient {
568    /// Create a new death recipient that will call the given callback when its
569    /// associated object dies.
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.
606    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.
623    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.
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.
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.
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.
676unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
677    fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
678        self.recipient
679    }
680
681    fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
682        self.recipient
683    }
684}
685
686impl Drop for DeathRecipient {
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.
708pub 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.
713    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.
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`.
723unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
724    fn as_native(&self) -> *const sys::AIBinder {
725        self.as_binder().as_native()
726    }
727
728    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.
735unsafe impl AsNative<sys::AIBinder> for SpIBinder {
736    fn as_native(&self) -> *const sys::AIBinder {
737        self.0.as_ptr()
738    }
739
740    fn as_native_mut(&mut self) -> *mut sys::AIBinder {
741        self.0.as_ptr()
742    }
743}