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