blob: ed3b9ec5c361ad6608f083ef646838033cbf3cb3 [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
19use crate::error::{status_t, Result};
20use crate::parcel::Parcel;
21use crate::proxy::{DeathRecipient, SpIBinder};
22use crate::sys;
23
Stephen Crane669deb62020-09-10 17:31:39 -070024use std::ffi::{c_void, CStr, CString};
25use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070026use std::os::unix::io::AsRawFd;
27use std::ptr;
28
29/// Binder action to perform.
30///
31/// This must be a number between [`IBinder::FIRST_CALL_TRANSACTION`] and
32/// [`IBinder::LAST_CALL_TRANSACTION`].
33pub type TransactionCode = u32;
34
35/// Additional operation flags.
36///
Steven Morelandf183fdd2020-10-27 00:12:12 +000037/// `IBinder::FLAG_*` values.
Stephen Crane2a3c2502020-06-16 17:48:35 -070038pub type TransactionFlags = u32;
39
40/// Super-trait for Binder interfaces.
41///
42/// This trait allows conversion of a Binder interface trait object into an
43/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
44/// interfaces) must implement this trait.
45///
46/// This is equivalent `IInterface` in C++.
47pub trait Interface {
48 /// Convert this binder object into a generic [`SpIBinder`] reference.
49 fn as_binder(&self) -> SpIBinder {
50 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
51 }
52}
53
54/// A local service that can be remotable via Binder.
55///
56/// An object that implement this interface made be made into a Binder service
57/// via `Binder::new(object)`.
58///
59/// This is a low-level interface that should normally be automatically
60/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
61/// the AIDL backend, users need only implement the high-level AIDL-defined
62/// interface. The AIDL compiler then generates a container struct that wraps
63/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -070064pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070065 /// The Binder interface descriptor string.
66 ///
67 /// This string is a unique identifier for a Binder interface, and should be
68 /// the same between all implementations of that interface.
69 fn get_descriptor() -> &'static str;
70
71 /// Handle and reply to a request to invoke a transaction on this object.
72 ///
73 /// `reply` may be [`None`] if the sender does not expect a reply.
74 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
75
76 /// Retrieve the class of this remote object.
77 ///
78 /// This method should always return the same InterfaceClass for the same
79 /// type.
80 fn get_class() -> InterfaceClass;
81}
82
83/// Interface of binder local or remote objects.
84///
85/// This trait corresponds to the interface of the C++ `IBinder` class.
86pub trait IBinder {
87 /// First transaction code available for user commands (inclusive)
88 const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
89 /// Last transaction code available for user commands (inclusive)
90 const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
91
92 /// Corresponds to TF_ONE_WAY -- an asynchronous call.
93 const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
Steven Morelandf183fdd2020-10-27 00:12:12 +000094 /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
95 const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Crane2a3c2502020-06-16 17:48:35 -070096
97 /// Is this object still alive?
98 fn is_binder_alive(&self) -> bool;
99
100 /// Send a ping transaction to this object
101 fn ping_binder(&mut self) -> Result<()>;
102
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700103 /// Indicate that the service intends to receive caller security contexts.
104 fn set_requesting_sid(&mut self, enable: bool);
105
Stephen Crane2a3c2502020-06-16 17:48:35 -0700106 /// Dump this object to the given file handle
107 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
108
109 /// Get a new interface that exposes additional extension functionality, if
110 /// available.
111 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
112
113 /// Perform a generic operation with the object.
114 ///
115 /// # Arguments
116 /// * `code` - Transaction code for the operation
117 /// * `data` - [`Parcel`] with input data
118 /// * `reply` - Optional [`Parcel`] for reply data
119 /// * `flags` - Transaction flags, e.g. marking the transaction as
120 /// asynchronous ([`FLAG_ONEWAY`](IBinder::FLAG_ONEWAY))
121 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
122 &self,
123 code: TransactionCode,
124 flags: TransactionFlags,
125 input_callback: F,
126 ) -> Result<Parcel>;
127
128 /// Register the recipient for a notification if this binder
129 /// goes away. If this binder object unexpectedly goes away
130 /// (typically because its hosting process has been killed),
131 /// then DeathRecipient::binder_died() will be called with a reference
132 /// to this.
133 ///
134 /// You will only receive death notifications for remote binders,
135 /// as local binders by definition can't die without you dying as well.
136 /// Trying to use this function on a local binder will result in an
137 /// INVALID_OPERATION code being returned and nothing happening.
138 ///
139 /// This link always holds a weak reference to its recipient.
140 ///
141 /// You will only receive a weak reference to the dead
142 /// binder. You should not try to promote this to a strong reference.
143 /// (Nor should you need to, as there is nothing useful you can
144 /// directly do with it now that it has passed on.)
145 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
146
147 /// Remove a previously registered death notification.
148 /// The recipient will no longer be called if this object
149 /// dies.
150 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
151}
152
153/// Opaque reference to the type of a Binder interface.
154///
155/// This object encapsulates the Binder interface descriptor string, along with
156/// the binder transaction callback, if the class describes a local service.
157///
158/// A Binder remotable object may only have a single interface class, and any
159/// given object can only be associated with one class. Two objects with
160/// different classes are incompatible, even if both classes have the same
161/// interface descriptor.
162#[derive(Copy, Clone, PartialEq, Eq)]
163pub struct InterfaceClass(*const sys::AIBinder_Class);
164
165impl InterfaceClass {
166 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
167 ///
168 /// Note: the returned pointer will not be constant. Calling this method
169 /// multiple times for the same type will result in distinct class
170 /// pointers. A static getter for this value is implemented in
171 /// [`declare_binder_interface!`].
172 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
173 let descriptor = CString::new(I::get_descriptor()).unwrap();
174 let ptr = unsafe {
175 // Safety: `AIBinder_Class_define` expects a valid C string, and
176 // three valid callback functions, all non-null pointers. The C
177 // string is copied and need not be valid for longer than the call,
178 // so we can drop it after the call. We can safely assign null to
179 // the onDump and handleShellCommand callbacks as long as the class
180 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
181 // be a NULL pointer. Rust retains ownership of the pointer after it
182 // is defined.
183 let class = sys::AIBinder_Class_define(
184 descriptor.as_ptr(),
185 Some(I::on_create),
186 Some(I::on_destroy),
187 Some(I::on_transact),
188 );
189 if class.is_null() {
190 panic!("Expected non-null class pointer from AIBinder_Class_define!");
191 }
192 sys::AIBinder_Class_setOnDump(class, None);
193 sys::AIBinder_Class_setHandleShellCommand(class, None);
194 class
195 };
196 InterfaceClass(ptr)
197 }
198
199 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
200 /// pointer.
201 ///
202 /// # Safety
203 ///
204 /// This function is safe iff `ptr` is a valid, non-null pointer to an
205 /// `AIBinder_Class`.
206 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
207 InterfaceClass(ptr)
208 }
Stephen Crane669deb62020-09-10 17:31:39 -0700209
210 /// Get the interface descriptor string of this class.
211 pub fn get_descriptor(&self) -> String {
212 unsafe {
213 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
214 // is always a two-byte null terminated sequence of u16s. Thus, we
215 // can continue reading from the pointer until we hit a null value,
216 // and this pointer can be a valid slice if the slice length is <=
217 // the number of u16 elements before the null terminator.
218
219 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
220 CStr::from_ptr(raw_descriptor).to_str()
221 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
222 .into()
223 }
224 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700225}
226
227impl From<InterfaceClass> for *const sys::AIBinder_Class {
228 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
229 class.0
230 }
231}
232
233/// Create a function implementing a static getter for an interface class.
234///
235/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
236/// [`Interface`]) must have global, static class that uniquely identifies
237/// it. This macro implements an [`InterfaceClass`] getter to simplify these
238/// implementations.
239///
240/// The type of a structure that implements [`InterfaceClassMethods`] must be
241/// passed to this macro. For local services, this should be `Binder<Self>`
242/// since [`Binder`] implements [`InterfaceClassMethods`].
243///
244/// # Examples
245///
246/// When implementing a local [`Remotable`] service `ExampleService`, the
247/// `get_class` method is required in the [`Remotable`] impl block. This macro
248/// should be used as follows to implement this functionality:
249///
250/// ```rust
251/// impl Remotable for ExampleService {
252/// fn get_descriptor() -> &'static str {
253/// "android.os.IExampleInterface"
254/// }
255///
256/// fn on_transact(
257/// &self,
258/// code: TransactionCode,
259/// data: &Parcel,
260/// reply: &mut Parcel,
261/// ) -> Result<()> {
262/// // ...
263/// }
264///
265/// binder_fn_get_class!(Binder<Self>);
266/// }
267/// ```
268macro_rules! binder_fn_get_class {
269 ($class:ty) => {
270 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
271 };
272
273 ($constructor:expr) => {
274 fn get_class() -> $crate::InterfaceClass {
275 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
276 static mut CLASS: Option<$crate::InterfaceClass> = None;
277
278 CLASS_INIT.call_once(|| unsafe {
279 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
280 // variable, and therefore is thread-safe, as it can only occur
281 // once.
282 CLASS = Some($constructor);
283 });
284 unsafe {
285 // Safety: The `CLASS` variable can only be mutated once, above,
286 // and is subsequently safe to read from any thread.
287 CLASS.unwrap()
288 }
289 }
290 };
291}
292
293pub trait InterfaceClassMethods {
294 /// Get the interface descriptor string for this object type.
295 fn get_descriptor() -> &'static str
296 where
297 Self: Sized;
298
299 /// Called during construction of a new `AIBinder` object of this interface
300 /// class.
301 ///
302 /// The opaque pointer parameter will be the parameter provided to
303 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
304 /// `AIBinder` object.
305 ///
306 /// # Safety
307 ///
308 /// Callback called from C++. The parameter argument provided to
309 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
310 /// will take ownership of the returned pointer, which it will free via
311 /// `on_destroy`.
312 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
313
314 /// Called when a transaction needs to be processed by the local service
315 /// implementation.
316 ///
317 /// # Safety
318 ///
319 /// Callback called from C++. The `binder` parameter must be a valid pointer
320 /// to a binder object of this class with userdata initialized via this
321 /// class's `on_create`. The parcel parameters must be valid pointers to
322 /// parcel objects.
323 unsafe extern "C" fn on_transact(
324 binder: *mut sys::AIBinder,
325 code: u32,
326 data: *const sys::AParcel,
327 reply: *mut sys::AParcel,
328 ) -> status_t;
329
330 /// Called whenever an `AIBinder` object is no longer referenced and needs
331 /// to be destroyed.
332 ///
333 /// # Safety
334 ///
335 /// Callback called from C++. The opaque pointer parameter must be the value
336 /// returned by `on_create` for this class. This function takes ownership of
337 /// the provided pointer and destroys it.
338 unsafe extern "C" fn on_destroy(object: *mut c_void);
339}
340
341/// Interface for transforming a generic SpIBinder into a specific remote
342/// interface trait.
343///
344/// # Example
345///
346/// For Binder interface `IFoo`, the following implementation should be made:
347/// ```no_run
348/// # use binder::{FromIBinder, SpIBinder, Result};
349/// # trait IFoo {}
350/// impl FromIBinder for dyn IFoo {
351/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
352/// // ...
353/// # Err(binder::StatusCode::OK)
354/// }
355/// }
356/// ```
357pub trait FromIBinder {
358 /// Try to interpret a generic Binder object as this interface.
359 ///
360 /// Returns a trait object for the `Self` interface if this object
361 /// implements that interface.
362 fn try_from(ibinder: SpIBinder) -> Result<Box<Self>>;
363}
364
365/// Trait for transparent Rust wrappers around android C++ native types.
366///
367/// The pointer return by this trait's methods should be immediately passed to
368/// C++ and not stored by Rust. The pointer is valid only as long as the
369/// underlying C++ object is alive, so users must be careful to take this into
370/// account, as Rust cannot enforce this.
371///
372/// # Safety
373///
374/// For this trait to be a correct implementation, `T` must be a valid android
375/// C++ type. Since we cannot constrain this via the type system, this trait is
376/// marked as unsafe.
377pub unsafe trait AsNative<T> {
378 /// Return a pointer to the native version of `self`
379 fn as_native(&self) -> *const T;
380
381 /// Return a mutable pointer to the native version of `self`
382 fn as_native_mut(&mut self) -> *mut T;
383}
384
385unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
386 fn as_native(&self) -> *const T {
387 self.as_ref().map_or(ptr::null(), |v| v.as_native())
388 }
389
390 fn as_native_mut(&mut self) -> *mut T {
391 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
392 }
393}
394
395/// Declare typed interfaces for a binder object.
396///
397/// Given an interface trait and descriptor string, create a native and remote
398/// proxy wrapper for this interface. The native service object (`$native`)
399/// implements `Remotable` and will dispatch to the function `$on_transact` to
400/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
401/// objects for this interface and can optionally contain additional fields.
402///
403/// Assuming the interface trait is `Interface`, `$on_transact` function must
404/// have the following type:
405///
406/// ```
407/// # use binder::{Interface, TransactionCode, Parcel};
408/// # trait Placeholder {
409/// fn on_transact(
410/// service: &dyn Interface,
411/// code: TransactionCode,
412/// data: &Parcel,
413/// reply: &mut Parcel,
414/// ) -> binder::Result<()>;
415/// # }
416/// ```
417///
418/// # Examples
419///
420/// The following example declares the local service type `BnServiceManager` and
421/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
422/// proxy respectively) for the `IServiceManager` Binder interface. The
423/// interfaces will be identified by the descriptor string
424/// "android.os.IServiceManager". The local service will dispatch transactions
425/// using the provided function, `on_transact`.
426///
427/// ```
428/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
429///
430/// pub trait IServiceManager: Interface {
431/// // remote methods...
432/// }
433///
434/// declare_binder_interface! {
435/// IServiceManager["android.os.IServiceManager"] {
436/// native: BnServiceManager(on_transact),
437/// proxy: BpServiceManager,
438/// }
439/// }
440///
441/// fn on_transact(
442/// service: &dyn IServiceManager,
443/// code: TransactionCode,
444/// data: &Parcel,
445/// reply: &mut Parcel,
446/// ) -> binder::Result<()> {
447/// // ...
448/// Ok(())
449/// }
450///
451/// impl IServiceManager for BpServiceManager {
452/// // parceling/unparceling code for the IServiceManager emitted here
453/// }
454///
455/// impl IServiceManager for Binder<BnServiceManager> {
456/// // Forward calls to local implementation
457/// }
458/// ```
459#[macro_export]
460macro_rules! declare_binder_interface {
461 {
462 $interface:path[$descriptor:expr] {
463 native: $native:ident($on_transact:path),
464 proxy: $proxy:ident,
465 }
466 } => {
467 $crate::declare_binder_interface! {
468 $interface[$descriptor] {
469 native: $native($on_transact),
470 proxy: $proxy {},
471 }
472 }
473 };
474
475 {
476 $interface:path[$descriptor:expr] {
477 native: $native:ident($on_transact:path),
478 proxy: $proxy:ident {
479 $($fname:ident: $fty:ty = $finit:expr),*
480 },
481 }
482 } => {
483 $crate::declare_binder_interface! {
484 $interface[$descriptor] {
485 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
486 native: $native($on_transact),
487 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
488 proxy: $proxy {
489 $($fname: $fty = $finit),*
490 },
491 }
492 }
493 };
494
495 {
496 $interface:path[$descriptor:expr] {
497 @doc[$native_doc:expr]
498 native: $native:ident($on_transact:path),
499
500 @doc[$proxy_doc:expr]
501 proxy: $proxy:ident {
502 $($fname:ident: $fty:ty = $finit:expr),*
503 },
504 }
505 } => {
506 #[doc = $proxy_doc]
507 pub struct $proxy {
508 binder: $crate::SpIBinder,
509 $($fname: $fty,)*
510 }
511
512 impl $crate::Interface for $proxy {
513 fn as_binder(&self) -> $crate::SpIBinder {
514 self.binder.clone()
515 }
516 }
517
518 impl $crate::Proxy for $proxy
519 where
520 $proxy: $interface,
521 {
522 fn get_descriptor() -> &'static str {
523 $descriptor
524 }
525
526 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700527 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700528 }
529 }
530
531 #[doc = $native_doc]
532 #[repr(transparent)]
533 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
534
535 impl $native {
536 /// Create a new binder service.
537 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> impl $interface {
538 $crate::Binder::new($native(Box::new(inner)))
539 }
540 }
541
542 impl $crate::Remotable for $native {
543 fn get_descriptor() -> &'static str {
544 $descriptor
545 }
546
547 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700548 match $on_transact(&*self.0, code, data, reply) {
549 // The C++ backend converts UNEXPECTED_NULL into an exception
550 Err($crate::StatusCode::UNEXPECTED_NULL) => {
551 let status = $crate::Status::new_exception(
552 $crate::ExceptionCode::NULL_POINTER,
553 None,
554 );
555 reply.write(&status)
556 },
557 result => result
558 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700559 }
560
561 fn get_class() -> $crate::InterfaceClass {
562 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
563 static mut CLASS: Option<$crate::InterfaceClass> = None;
564
565 CLASS_INIT.call_once(|| unsafe {
566 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
567 // variable, and therefore is thread-safe, as it can only occur
568 // once.
569 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
570 });
571 unsafe {
572 // Safety: The `CLASS` variable can only be mutated once, above,
573 // and is subsequently safe to read from any thread.
574 CLASS.unwrap()
575 }
576 }
577 }
578
579 impl $crate::FromIBinder for dyn $interface {
580 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
581 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700582
583 let existing_class = ibinder.get_class();
584 if let Some(class) = existing_class {
585 if class != <$native as $crate::Remotable>::get_class() &&
586 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
587 {
588 // The binder object's descriptor string matches what we
589 // expect. We still need to treat this local or already
590 // associated object as remote, because we can't cast it
591 // into a Rust service object without a matching class
592 // pointer.
593 return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
594 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700595 }
596
Stephen Crane669deb62020-09-10 17:31:39 -0700597 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
598 let service: $crate::Result<$crate::Binder<$native>> =
599 std::convert::TryFrom::try_from(ibinder.clone());
600 if let Ok(service) = service {
601 // We were able to associate with our expected class and
602 // the service is local.
603 return Ok(Box::new(service));
604 } else {
605 // Service is remote
606 return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
607 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000608 }
Stephen Crane669deb62020-09-10 17:31:39 -0700609
610 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700611 }
612 }
613
614 impl $crate::parcel::Serialize for dyn $interface + '_
615 where
616 $interface: $crate::Interface
617 {
618 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
619 let binder = $crate::Interface::as_binder(self);
620 parcel.write(&binder)
621 }
622 }
623
624 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
625 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
626 parcel.write(&this.map($crate::Interface::as_binder))
627 }
628 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700629
630 impl std::fmt::Debug for dyn $interface {
631 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
632 f.pad(stringify!($interface))
633 }
634 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700635
636 // Convert a &dyn $interface to Box<dyn $interface>
637 impl std::borrow::ToOwned for dyn $interface {
638 type Owned = Box<dyn $interface>;
639 fn to_owned(&self) -> Self::Owned {
640 self.as_binder().into_interface()
641 .expect(concat!("Error cloning interface ", stringify!($interface)))
642 }
643 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700644 };
645}
Andrei Homescu00eca712020-09-09 18:57:40 -0700646
647/// Declare an AIDL enumeration.
648///
649/// This is mainly used internally by the AIDL compiler.
650#[macro_export]
651macro_rules! declare_binder_enum {
652 {
653 $enum:ident : $backing:ty {
654 $( $name:ident = $value:expr, )*
655 }
656 } => {
657 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
658 pub struct $enum(pub $backing);
659 impl $enum {
660 $( pub const $name: Self = Self($value); )*
661 }
662
663 impl $crate::parcel::Serialize for $enum {
664 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
665 parcel.write(&self.0)
666 }
667 }
668
669 impl $crate::parcel::SerializeArray for $enum {
670 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
671 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
672 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
673 }
674 }
675
676 impl $crate::parcel::Deserialize for $enum {
677 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
678 parcel.read().map(Self)
679 }
680 }
681
682 impl $crate::parcel::DeserializeArray for $enum {
683 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
684 let v: Option<Vec<$backing>> =
685 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
686 Ok(v.map(|v| v.into_iter().map(Self).collect()))
687 }
688 }
689 };
690}