blob: d53a88f72689ffca0448a5ca3cfb4573feb9c076 [file] [log] [blame]
Stephen Crane2a3c2502020-06-16 17:48:35 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Trait definitions for binder objects
18
Stephen Craneddb3e6d2020-12-18 13:27:22 -080019use crate::error::{status_t, Result, StatusCode};
Stephen Crane2a3c2502020-06-16 17:48:35 -070020use crate::parcel::Parcel;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080021use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
Stephen Crane2a3c2502020-06-16 17:48:35 -070022use crate::sys;
23
Stephen Craneddb3e6d2020-12-18 13:27:22 -080024use std::borrow::Borrow;
25use std::cmp::Ordering;
Stephen Crane669deb62020-09-10 17:31:39 -070026use std::ffi::{c_void, CStr, CString};
Stephen Craneddb3e6d2020-12-18 13:27:22 -080027use std::fmt;
28use std::marker::PhantomData;
29use std::ops::Deref;
Stephen Crane669deb62020-09-10 17:31:39 -070030use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070031use std::os::unix::io::AsRawFd;
32use std::ptr;
33
34/// Binder action to perform.
35///
36/// This must be a number between [`IBinder::FIRST_CALL_TRANSACTION`] and
37/// [`IBinder::LAST_CALL_TRANSACTION`].
38pub type TransactionCode = u32;
39
40/// Additional operation flags.
41///
Steven Morelandf183fdd2020-10-27 00:12:12 +000042/// `IBinder::FLAG_*` values.
Stephen Crane2a3c2502020-06-16 17:48:35 -070043pub type TransactionFlags = u32;
44
45/// Super-trait for Binder interfaces.
46///
47/// This trait allows conversion of a Binder interface trait object into an
48/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
49/// interfaces) must implement this trait.
50///
51/// This is equivalent `IInterface` in C++.
Stephen Craneddb3e6d2020-12-18 13:27:22 -080052pub trait Interface: Send {
Stephen Crane2a3c2502020-06-16 17:48:35 -070053 /// Convert this binder object into a generic [`SpIBinder`] reference.
54 fn as_binder(&self) -> SpIBinder {
55 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
56 }
57}
58
59/// A local service that can be remotable via Binder.
60///
61/// An object that implement this interface made be made into a Binder service
62/// via `Binder::new(object)`.
63///
64/// This is a low-level interface that should normally be automatically
65/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
66/// the AIDL backend, users need only implement the high-level AIDL-defined
67/// interface. The AIDL compiler then generates a container struct that wraps
68/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -070069pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070070 /// The Binder interface descriptor string.
71 ///
72 /// This string is a unique identifier for a Binder interface, and should be
73 /// the same between all implementations of that interface.
74 fn get_descriptor() -> &'static str;
75
76 /// Handle and reply to a request to invoke a transaction on this object.
77 ///
78 /// `reply` may be [`None`] if the sender does not expect a reply.
79 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
80
81 /// Retrieve the class of this remote object.
82 ///
83 /// This method should always return the same InterfaceClass for the same
84 /// type.
85 fn get_class() -> InterfaceClass;
86}
87
88/// Interface of binder local or remote objects.
89///
90/// This trait corresponds to the interface of the C++ `IBinder` class.
91pub trait IBinder {
92 /// First transaction code available for user commands (inclusive)
93 const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
94 /// Last transaction code available for user commands (inclusive)
95 const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
96
97 /// Corresponds to TF_ONE_WAY -- an asynchronous call.
98 const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
Steven Morelandf183fdd2020-10-27 00:12:12 +000099 /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
100 const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700101
102 /// Is this object still alive?
103 fn is_binder_alive(&self) -> bool;
104
105 /// Send a ping transaction to this object
106 fn ping_binder(&mut self) -> Result<()>;
107
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700108 /// Indicate that the service intends to receive caller security contexts.
109 fn set_requesting_sid(&mut self, enable: bool);
110
Stephen Crane2a3c2502020-06-16 17:48:35 -0700111 /// Dump this object to the given file handle
112 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
113
114 /// Get a new interface that exposes additional extension functionality, if
115 /// available.
116 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
117
118 /// Perform a generic operation with the object.
119 ///
120 /// # Arguments
121 /// * `code` - Transaction code for the operation
122 /// * `data` - [`Parcel`] with input data
123 /// * `reply` - Optional [`Parcel`] for reply data
124 /// * `flags` - Transaction flags, e.g. marking the transaction as
125 /// asynchronous ([`FLAG_ONEWAY`](IBinder::FLAG_ONEWAY))
126 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
127 &self,
128 code: TransactionCode,
129 flags: TransactionFlags,
130 input_callback: F,
131 ) -> Result<Parcel>;
132
133 /// Register the recipient for a notification if this binder
134 /// goes away. If this binder object unexpectedly goes away
135 /// (typically because its hosting process has been killed),
136 /// then DeathRecipient::binder_died() will be called with a reference
137 /// to this.
138 ///
139 /// You will only receive death notifications for remote binders,
140 /// as local binders by definition can't die without you dying as well.
141 /// Trying to use this function on a local binder will result in an
142 /// INVALID_OPERATION code being returned and nothing happening.
143 ///
144 /// This link always holds a weak reference to its recipient.
145 ///
146 /// You will only receive a weak reference to the dead
147 /// binder. You should not try to promote this to a strong reference.
148 /// (Nor should you need to, as there is nothing useful you can
149 /// directly do with it now that it has passed on.)
150 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
151
152 /// Remove a previously registered death notification.
153 /// The recipient will no longer be called if this object
154 /// dies.
155 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
156}
157
158/// Opaque reference to the type of a Binder interface.
159///
160/// This object encapsulates the Binder interface descriptor string, along with
161/// the binder transaction callback, if the class describes a local service.
162///
163/// A Binder remotable object may only have a single interface class, and any
164/// given object can only be associated with one class. Two objects with
165/// different classes are incompatible, even if both classes have the same
166/// interface descriptor.
167#[derive(Copy, Clone, PartialEq, Eq)]
168pub struct InterfaceClass(*const sys::AIBinder_Class);
169
170impl InterfaceClass {
171 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
172 ///
173 /// Note: the returned pointer will not be constant. Calling this method
174 /// multiple times for the same type will result in distinct class
175 /// pointers. A static getter for this value is implemented in
176 /// [`declare_binder_interface!`].
177 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
178 let descriptor = CString::new(I::get_descriptor()).unwrap();
179 let ptr = unsafe {
180 // Safety: `AIBinder_Class_define` expects a valid C string, and
181 // three valid callback functions, all non-null pointers. The C
182 // string is copied and need not be valid for longer than the call,
183 // so we can drop it after the call. We can safely assign null to
184 // the onDump and handleShellCommand callbacks as long as the class
185 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
186 // be a NULL pointer. Rust retains ownership of the pointer after it
187 // is defined.
188 let class = sys::AIBinder_Class_define(
189 descriptor.as_ptr(),
190 Some(I::on_create),
191 Some(I::on_destroy),
192 Some(I::on_transact),
193 );
194 if class.is_null() {
195 panic!("Expected non-null class pointer from AIBinder_Class_define!");
196 }
197 sys::AIBinder_Class_setOnDump(class, None);
198 sys::AIBinder_Class_setHandleShellCommand(class, None);
199 class
200 };
201 InterfaceClass(ptr)
202 }
203
204 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
205 /// pointer.
206 ///
207 /// # Safety
208 ///
209 /// This function is safe iff `ptr` is a valid, non-null pointer to an
210 /// `AIBinder_Class`.
211 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
212 InterfaceClass(ptr)
213 }
Stephen Crane669deb62020-09-10 17:31:39 -0700214
215 /// Get the interface descriptor string of this class.
216 pub fn get_descriptor(&self) -> String {
217 unsafe {
218 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
219 // is always a two-byte null terminated sequence of u16s. Thus, we
220 // can continue reading from the pointer until we hit a null value,
221 // and this pointer can be a valid slice if the slice length is <=
222 // the number of u16 elements before the null terminator.
223
224 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
225 CStr::from_ptr(raw_descriptor).to_str()
226 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
227 .into()
228 }
229 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700230}
231
232impl From<InterfaceClass> for *const sys::AIBinder_Class {
233 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
234 class.0
235 }
236}
237
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800238/// Strong reference to a binder object
239pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
240
241impl<I: FromIBinder + ?Sized> Strong<I> {
242 /// Create a new strong reference to the provided binder object
243 pub fn new(binder: Box<I>) -> Self {
244 Self(binder)
245 }
246
247 /// Construct a new weak reference to this binder
248 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
249 Weak::new(this)
250 }
251}
252
253impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
254 fn clone(&self) -> Self {
255 // Since we hold a strong reference, we should always be able to create
256 // a new strong reference to the same interface type, so try_from()
257 // should never fail here.
258 FromIBinder::try_from(self.0.as_binder()).unwrap()
259 }
260}
261
262impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
263 fn borrow(&self) -> &I {
264 &self.0
265 }
266}
267
268impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
269 fn as_ref(&self) -> &I {
270 &self.0
271 }
272}
273
274impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
275 type Target = I;
276
277 fn deref(&self) -> &Self::Target {
278 &self.0
279 }
280}
281
282impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
283 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
284 fmt::Debug::fmt(&**self, f)
285 }
286}
287
288impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
289 fn cmp(&self, other: &Self) -> Ordering {
290 self.0.as_binder().cmp(&other.0.as_binder())
291 }
292}
293
294impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
295 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
296 self.0.as_binder().partial_cmp(&other.0.as_binder())
297 }
298}
299
300impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
301 fn eq(&self, other: &Self) -> bool {
302 self.0.as_binder().eq(&other.0.as_binder())
303 }
304}
305
306impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
307
308/// Weak reference to a binder object
309#[derive(Debug)]
310pub struct Weak<I: FromIBinder + ?Sized> {
311 weak_binder: WpIBinder,
312 interface_type: PhantomData<I>,
313}
314
315impl<I: FromIBinder + ?Sized> Weak<I> {
316 /// Construct a new weak reference from a strong reference
317 fn new(binder: &Strong<I>) -> Self {
318 let weak_binder = binder.as_binder().downgrade();
319 Weak {
320 weak_binder,
321 interface_type: PhantomData,
322 }
323 }
324
325 /// Upgrade this weak reference to a strong reference if the binder object
326 /// is still alive
327 pub fn upgrade(&self) -> Result<Strong<I>> {
328 self.weak_binder
329 .promote()
330 .ok_or(StatusCode::DEAD_OBJECT)
331 .and_then(FromIBinder::try_from)
332 }
333}
334
335impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
336 fn clone(&self) -> Self {
337 Self {
338 weak_binder: self.weak_binder.clone(),
339 interface_type: PhantomData,
340 }
341 }
342}
343
344impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
345 fn cmp(&self, other: &Self) -> Ordering {
346 self.weak_binder.cmp(&other.weak_binder)
347 }
348}
349
350impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
351 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
352 self.weak_binder.partial_cmp(&other.weak_binder)
353 }
354}
355
356impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
357 fn eq(&self, other: &Self) -> bool {
358 self.weak_binder == other.weak_binder
359 }
360}
361
362impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
363
Stephen Crane2a3c2502020-06-16 17:48:35 -0700364/// Create a function implementing a static getter for an interface class.
365///
366/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
367/// [`Interface`]) must have global, static class that uniquely identifies
368/// it. This macro implements an [`InterfaceClass`] getter to simplify these
369/// implementations.
370///
371/// The type of a structure that implements [`InterfaceClassMethods`] must be
372/// passed to this macro. For local services, this should be `Binder<Self>`
373/// since [`Binder`] implements [`InterfaceClassMethods`].
374///
375/// # Examples
376///
377/// When implementing a local [`Remotable`] service `ExampleService`, the
378/// `get_class` method is required in the [`Remotable`] impl block. This macro
379/// should be used as follows to implement this functionality:
380///
381/// ```rust
382/// impl Remotable for ExampleService {
383/// fn get_descriptor() -> &'static str {
384/// "android.os.IExampleInterface"
385/// }
386///
387/// fn on_transact(
388/// &self,
389/// code: TransactionCode,
390/// data: &Parcel,
391/// reply: &mut Parcel,
392/// ) -> Result<()> {
393/// // ...
394/// }
395///
396/// binder_fn_get_class!(Binder<Self>);
397/// }
398/// ```
399macro_rules! binder_fn_get_class {
400 ($class:ty) => {
401 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
402 };
403
404 ($constructor:expr) => {
405 fn get_class() -> $crate::InterfaceClass {
406 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
407 static mut CLASS: Option<$crate::InterfaceClass> = None;
408
409 CLASS_INIT.call_once(|| unsafe {
410 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
411 // variable, and therefore is thread-safe, as it can only occur
412 // once.
413 CLASS = Some($constructor);
414 });
415 unsafe {
416 // Safety: The `CLASS` variable can only be mutated once, above,
417 // and is subsequently safe to read from any thread.
418 CLASS.unwrap()
419 }
420 }
421 };
422}
423
424pub trait InterfaceClassMethods {
425 /// Get the interface descriptor string for this object type.
426 fn get_descriptor() -> &'static str
427 where
428 Self: Sized;
429
430 /// Called during construction of a new `AIBinder` object of this interface
431 /// class.
432 ///
433 /// The opaque pointer parameter will be the parameter provided to
434 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
435 /// `AIBinder` object.
436 ///
437 /// # Safety
438 ///
439 /// Callback called from C++. The parameter argument provided to
440 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
441 /// will take ownership of the returned pointer, which it will free via
442 /// `on_destroy`.
443 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
444
445 /// Called when a transaction needs to be processed by the local service
446 /// implementation.
447 ///
448 /// # Safety
449 ///
450 /// Callback called from C++. The `binder` parameter must be a valid pointer
451 /// to a binder object of this class with userdata initialized via this
452 /// class's `on_create`. The parcel parameters must be valid pointers to
453 /// parcel objects.
454 unsafe extern "C" fn on_transact(
455 binder: *mut sys::AIBinder,
456 code: u32,
457 data: *const sys::AParcel,
458 reply: *mut sys::AParcel,
459 ) -> status_t;
460
461 /// Called whenever an `AIBinder` object is no longer referenced and needs
462 /// to be destroyed.
463 ///
464 /// # Safety
465 ///
466 /// Callback called from C++. The opaque pointer parameter must be the value
467 /// returned by `on_create` for this class. This function takes ownership of
468 /// the provided pointer and destroys it.
469 unsafe extern "C" fn on_destroy(object: *mut c_void);
470}
471
472/// Interface for transforming a generic SpIBinder into a specific remote
473/// interface trait.
474///
475/// # Example
476///
477/// For Binder interface `IFoo`, the following implementation should be made:
478/// ```no_run
479/// # use binder::{FromIBinder, SpIBinder, Result};
480/// # trait IFoo {}
481/// impl FromIBinder for dyn IFoo {
482/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
483/// // ...
484/// # Err(binder::StatusCode::OK)
485/// }
486/// }
487/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800488pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700489 /// Try to interpret a generic Binder object as this interface.
490 ///
491 /// Returns a trait object for the `Self` interface if this object
492 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800493 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700494}
495
496/// Trait for transparent Rust wrappers around android C++ native types.
497///
498/// The pointer return by this trait's methods should be immediately passed to
499/// C++ and not stored by Rust. The pointer is valid only as long as the
500/// underlying C++ object is alive, so users must be careful to take this into
501/// account, as Rust cannot enforce this.
502///
503/// # Safety
504///
505/// For this trait to be a correct implementation, `T` must be a valid android
506/// C++ type. Since we cannot constrain this via the type system, this trait is
507/// marked as unsafe.
508pub unsafe trait AsNative<T> {
509 /// Return a pointer to the native version of `self`
510 fn as_native(&self) -> *const T;
511
512 /// Return a mutable pointer to the native version of `self`
513 fn as_native_mut(&mut self) -> *mut T;
514}
515
516unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
517 fn as_native(&self) -> *const T {
518 self.as_ref().map_or(ptr::null(), |v| v.as_native())
519 }
520
521 fn as_native_mut(&mut self) -> *mut T {
522 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
523 }
524}
525
526/// Declare typed interfaces for a binder object.
527///
528/// Given an interface trait and descriptor string, create a native and remote
529/// proxy wrapper for this interface. The native service object (`$native`)
530/// implements `Remotable` and will dispatch to the function `$on_transact` to
531/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
532/// objects for this interface and can optionally contain additional fields.
533///
534/// Assuming the interface trait is `Interface`, `$on_transact` function must
535/// have the following type:
536///
537/// ```
538/// # use binder::{Interface, TransactionCode, Parcel};
539/// # trait Placeholder {
540/// fn on_transact(
541/// service: &dyn Interface,
542/// code: TransactionCode,
543/// data: &Parcel,
544/// reply: &mut Parcel,
545/// ) -> binder::Result<()>;
546/// # }
547/// ```
548///
549/// # Examples
550///
551/// The following example declares the local service type `BnServiceManager` and
552/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
553/// proxy respectively) for the `IServiceManager` Binder interface. The
554/// interfaces will be identified by the descriptor string
555/// "android.os.IServiceManager". The local service will dispatch transactions
556/// using the provided function, `on_transact`.
557///
558/// ```
559/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
560///
561/// pub trait IServiceManager: Interface {
562/// // remote methods...
563/// }
564///
565/// declare_binder_interface! {
566/// IServiceManager["android.os.IServiceManager"] {
567/// native: BnServiceManager(on_transact),
568/// proxy: BpServiceManager,
569/// }
570/// }
571///
572/// fn on_transact(
573/// service: &dyn IServiceManager,
574/// code: TransactionCode,
575/// data: &Parcel,
576/// reply: &mut Parcel,
577/// ) -> binder::Result<()> {
578/// // ...
579/// Ok(())
580/// }
581///
582/// impl IServiceManager for BpServiceManager {
583/// // parceling/unparceling code for the IServiceManager emitted here
584/// }
585///
586/// impl IServiceManager for Binder<BnServiceManager> {
587/// // Forward calls to local implementation
588/// }
589/// ```
590#[macro_export]
591macro_rules! declare_binder_interface {
592 {
593 $interface:path[$descriptor:expr] {
594 native: $native:ident($on_transact:path),
595 proxy: $proxy:ident,
596 }
597 } => {
598 $crate::declare_binder_interface! {
599 $interface[$descriptor] {
600 native: $native($on_transact),
601 proxy: $proxy {},
602 }
603 }
604 };
605
606 {
607 $interface:path[$descriptor:expr] {
608 native: $native:ident($on_transact:path),
609 proxy: $proxy:ident {
610 $($fname:ident: $fty:ty = $finit:expr),*
611 },
612 }
613 } => {
614 $crate::declare_binder_interface! {
615 $interface[$descriptor] {
616 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
617 native: $native($on_transact),
618 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
619 proxy: $proxy {
620 $($fname: $fty = $finit),*
621 },
622 }
623 }
624 };
625
626 {
627 $interface:path[$descriptor:expr] {
628 @doc[$native_doc:expr]
629 native: $native:ident($on_transact:path),
630
631 @doc[$proxy_doc:expr]
632 proxy: $proxy:ident {
633 $($fname:ident: $fty:ty = $finit:expr),*
634 },
635 }
636 } => {
637 #[doc = $proxy_doc]
638 pub struct $proxy {
639 binder: $crate::SpIBinder,
640 $($fname: $fty,)*
641 }
642
643 impl $crate::Interface for $proxy {
644 fn as_binder(&self) -> $crate::SpIBinder {
645 self.binder.clone()
646 }
647 }
648
649 impl $crate::Proxy for $proxy
650 where
651 $proxy: $interface,
652 {
653 fn get_descriptor() -> &'static str {
654 $descriptor
655 }
656
657 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700658 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700659 }
660 }
661
662 #[doc = $native_doc]
663 #[repr(transparent)]
664 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
665
666 impl $native {
667 /// Create a new binder service.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800668 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
669 let binder = $crate::Binder::new($native(Box::new(inner)));
670 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700671 }
672 }
673
674 impl $crate::Remotable for $native {
675 fn get_descriptor() -> &'static str {
676 $descriptor
677 }
678
679 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700680 match $on_transact(&*self.0, code, data, reply) {
681 // The C++ backend converts UNEXPECTED_NULL into an exception
682 Err($crate::StatusCode::UNEXPECTED_NULL) => {
683 let status = $crate::Status::new_exception(
684 $crate::ExceptionCode::NULL_POINTER,
685 None,
686 );
687 reply.write(&status)
688 },
689 result => result
690 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700691 }
692
693 fn get_class() -> $crate::InterfaceClass {
694 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
695 static mut CLASS: Option<$crate::InterfaceClass> = None;
696
697 CLASS_INIT.call_once(|| unsafe {
698 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
699 // variable, and therefore is thread-safe, as it can only occur
700 // once.
701 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
702 });
703 unsafe {
704 // Safety: The `CLASS` variable can only be mutated once, above,
705 // and is subsequently safe to read from any thread.
706 CLASS.unwrap()
707 }
708 }
709 }
710
711 impl $crate::FromIBinder for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800712 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700713 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700714
715 let existing_class = ibinder.get_class();
716 if let Some(class) = existing_class {
717 if class != <$native as $crate::Remotable>::get_class() &&
718 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
719 {
720 // The binder object's descriptor string matches what we
721 // expect. We still need to treat this local or already
722 // associated object as remote, because we can't cast it
723 // into a Rust service object without a matching class
724 // pointer.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800725 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700726 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700727 }
728
Stephen Crane669deb62020-09-10 17:31:39 -0700729 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
730 let service: $crate::Result<$crate::Binder<$native>> =
731 std::convert::TryFrom::try_from(ibinder.clone());
732 if let Ok(service) = service {
733 // We were able to associate with our expected class and
734 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800735 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700736 } else {
737 // Service is remote
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800738 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700739 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000740 }
Stephen Crane669deb62020-09-10 17:31:39 -0700741
742 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700743 }
744 }
745
746 impl $crate::parcel::Serialize for dyn $interface + '_
747 where
Stephen Craned58bce02020-07-07 12:26:02 -0700748 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700749 {
750 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
751 let binder = $crate::Interface::as_binder(self);
752 parcel.write(&binder)
753 }
754 }
755
756 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
757 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
758 parcel.write(&this.map($crate::Interface::as_binder))
759 }
760 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700761
762 impl std::fmt::Debug for dyn $interface {
763 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
764 f.pad(stringify!($interface))
765 }
766 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700767
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800768 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700769 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800770 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700771 fn to_owned(&self) -> Self::Owned {
772 self.as_binder().into_interface()
773 .expect(concat!("Error cloning interface ", stringify!($interface)))
774 }
775 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700776 };
777}
Andrei Homescu00eca712020-09-09 18:57:40 -0700778
779/// Declare an AIDL enumeration.
780///
781/// This is mainly used internally by the AIDL compiler.
782#[macro_export]
783macro_rules! declare_binder_enum {
784 {
785 $enum:ident : $backing:ty {
786 $( $name:ident = $value:expr, )*
787 }
788 } => {
789 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
790 pub struct $enum(pub $backing);
791 impl $enum {
792 $( pub const $name: Self = Self($value); )*
793 }
794
795 impl $crate::parcel::Serialize for $enum {
796 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
797 parcel.write(&self.0)
798 }
799 }
800
801 impl $crate::parcel::SerializeArray for $enum {
802 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
803 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
804 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
805 }
806 }
807
808 impl $crate::parcel::Deserialize for $enum {
809 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
810 parcel.read().map(Self)
811 }
812 }
813
814 impl $crate::parcel::DeserializeArray for $enum {
815 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
816 let v: Option<Vec<$backing>> =
817 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
818 Ok(v.map(|v| v.into_iter().map(Self).collect()))
819 }
820 }
821 };
822}