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 //! Trait definitions for binder objects 18 19 use crate::error::{status_t, Result, StatusCode}; 20 use crate::parcel::{BorrowedParcel, Parcel}; 21 use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; 22 use crate::sys; 23 24 use downcast_rs::{impl_downcast, DowncastSync}; 25 use std::borrow::Borrow; 26 use std::cmp::Ordering; 27 use std::convert::TryFrom; 28 use std::ffi::{c_void, CStr, CString}; 29 use std::fmt; 30 use std::io::Write; 31 use std::marker::PhantomData; 32 use std::ops::Deref; 33 use std::os::fd::AsRawFd; 34 use std::os::raw::c_char; 35 use std::ptr; 36 37 /// Binder action to perform. 38 /// 39 /// This must be a number between [`FIRST_CALL_TRANSACTION`] and 40 /// [`LAST_CALL_TRANSACTION`]. 41 pub type TransactionCode = u32; 42 43 /// Additional operation flags. 44 /// 45 /// `FLAG_*` values. 46 pub type TransactionFlags = u32; 47 48 /// Super-trait for Binder interfaces. 49 /// 50 /// This trait allows conversion of a Binder interface trait object into an 51 /// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL 52 /// interfaces) must implement this trait. 53 /// 54 /// This is equivalent `IInterface` in C++. 55 pub trait Interface: Send + Sync + DowncastSync { 56 /// Convert this binder object into a generic [`SpIBinder`] reference. as_binder(&self) -> SpIBinder57 fn as_binder(&self) -> SpIBinder { 58 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.") 59 } 60 61 /// Dump transaction handler for this Binder object. 62 /// 63 /// This handler is a no-op by default and should be implemented for each 64 /// Binder service struct that wishes to respond to dump transactions. dump(&self, _writer: &mut dyn Write, _args: &[&CStr]) -> Result<()>65 fn dump(&self, _writer: &mut dyn Write, _args: &[&CStr]) -> Result<()> { 66 Ok(()) 67 } 68 } 69 70 impl_downcast!(sync Interface); 71 72 /// Implemented by sync interfaces to specify what the associated async interface is. 73 /// Generic to handle the fact that async interfaces are generic over a thread pool. 74 /// 75 /// The binder in any object implementing this trait should be compatible with the 76 /// `Target` associated type, and using `FromIBinder` to convert it to the target 77 /// should not fail. 78 pub trait ToAsyncInterface<P> 79 where 80 Self: Interface, 81 Self::Target: FromIBinder, 82 { 83 /// The async interface associated with this sync interface. 84 type Target: ?Sized; 85 } 86 87 /// Implemented by async interfaces to specify what the associated sync interface is. 88 /// 89 /// The binder in any object implementing this trait should be compatible with the 90 /// `Target` associated type, and using `FromIBinder` to convert it to the target 91 /// should not fail. 92 pub trait ToSyncInterface 93 where 94 Self: Interface, 95 Self::Target: FromIBinder, 96 { 97 /// The sync interface associated with this async interface. 98 type Target: ?Sized; 99 } 100 101 /// Interface stability promise 102 /// 103 /// An interface can promise to be a stable vendor interface ([`Stability::Vintf`]), 104 /// or makes no stability guarantees ([`Stability::Local`]). [`Stability::Local`] is 105 /// currently the default stability. 106 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)] 107 pub enum Stability { 108 /// Default stability, visible to other modules in the same compilation 109 /// context (e.g. modules on system.img) 110 #[default] 111 Local, 112 113 /// A Vendor Interface Object, which promises to be stable 114 Vintf, 115 } 116 117 impl From<Stability> for i32 { from(stability: Stability) -> i32118 fn from(stability: Stability) -> i32 { 119 use Stability::*; 120 match stability { 121 Local => 0, 122 Vintf => 1, 123 } 124 } 125 } 126 127 impl TryFrom<i32> for Stability { 128 type Error = StatusCode; try_from(stability: i32) -> Result<Stability>129 fn try_from(stability: i32) -> Result<Stability> { 130 use Stability::*; 131 match stability { 132 0 => Ok(Local), 133 1 => Ok(Vintf), 134 _ => Err(StatusCode::BAD_VALUE), 135 } 136 } 137 } 138 139 /// Same as `Stability`, but in the form of a trait. Used when the stability should be encoded in 140 /// the type. 141 /// 142 /// When/if the `adt_const_params` Rust feature is stabilized, this could be replace by using 143 /// `Stability` directly with const generics. 144 pub trait StabilityType { 145 /// The `Stability` represented by this type. 146 const VALUE: Stability; 147 } 148 149 /// `Stability::Local`. 150 #[derive(Debug)] 151 pub enum LocalStabilityType {} 152 /// `Stability::Vintf`. 153 #[derive(Debug)] 154 pub enum VintfStabilityType {} 155 156 impl StabilityType for LocalStabilityType { 157 const VALUE: Stability = Stability::Local; 158 } 159 160 impl StabilityType for VintfStabilityType { 161 const VALUE: Stability = Stability::Vintf; 162 } 163 164 /// A local service that can be remotable via Binder. 165 /// 166 /// An object that implement this interface made be made into a Binder service 167 /// via `Binder::new(object)`. 168 /// 169 /// This is a low-level interface that should normally be automatically 170 /// generated from AIDL via the [`crate::declare_binder_interface!`] macro. 171 /// When using the AIDL backend, users need only implement the high-level AIDL-defined 172 /// interface. The AIDL compiler then generates a container struct that wraps 173 /// the user-defined service and implements `Remotable`. 174 pub trait Remotable: Send + Sync + 'static { 175 /// The Binder interface descriptor string. 176 /// 177 /// This string is a unique identifier for a Binder interface, and should be 178 /// the same between all implementations of that interface. get_descriptor() -> &'static str179 fn get_descriptor() -> &'static str; 180 181 /// Handle and reply to a request to invoke a transaction on this object. 182 /// 183 /// `reply` may be [`None`] if the sender does not expect a reply. on_transact( &self, code: TransactionCode, data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>, ) -> Result<()>184 fn on_transact( 185 &self, 186 code: TransactionCode, 187 data: &BorrowedParcel<'_>, 188 reply: &mut BorrowedParcel<'_>, 189 ) -> Result<()>; 190 191 /// Handle a request to invoke the dump transaction on this 192 /// object. on_dump(&self, file: &mut dyn Write, args: &[&CStr]) -> Result<()>193 fn on_dump(&self, file: &mut dyn Write, args: &[&CStr]) -> Result<()>; 194 195 /// Retrieve the class of this remote object. 196 /// 197 /// This method should always return the same InterfaceClass for the same 198 /// type. get_class() -> InterfaceClass199 fn get_class() -> InterfaceClass; 200 } 201 202 /// First transaction code available for user commands (inclusive) 203 pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION; 204 /// Last transaction code available for user commands (inclusive) 205 pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION; 206 207 /// Corresponds to TF_ONE_WAY -- an asynchronous call. 208 pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY; 209 /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made. 210 #[cfg(not(android_ndk))] 211 pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF; 212 /// Set to the vendor flag if we are building for the VNDK, 0 otherwise 213 #[cfg(not(android_ndk))] 214 pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL; 215 216 /// Internal interface of binder local or remote objects for making 217 /// transactions. 218 /// 219 /// This trait corresponds to the parts of the interface of the C++ `IBinder` 220 /// class which are internal implementation details. 221 pub trait IBinderInternal: IBinder { 222 /// Is this object still alive? is_binder_alive(&self) -> bool223 fn is_binder_alive(&self) -> bool; 224 225 /// Indicate that the service intends to receive caller security contexts. 226 #[cfg(not(any(android_vndk, android_ndk)))] set_requesting_sid(&mut self, enable: bool)227 fn set_requesting_sid(&mut self, enable: bool); 228 229 /// Dump this object to the given file handle dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>230 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>; 231 232 /// Get a new interface that exposes additional extension functionality, if 233 /// available. get_extension(&mut self) -> Result<Option<SpIBinder>>234 fn get_extension(&mut self) -> Result<Option<SpIBinder>>; 235 236 /// Create a Parcel that can be used with `submit_transact`. prepare_transact(&self) -> Result<Parcel>237 fn prepare_transact(&self) -> Result<Parcel>; 238 239 /// Perform a generic operation with the object. 240 /// 241 /// The provided [`Parcel`] must have been created by a call to 242 /// `prepare_transact` on the same binder. 243 /// 244 /// # Arguments 245 /// 246 /// * `code` - Transaction code for the operation. 247 /// * `data` - [`Parcel`] with input data. 248 /// * `flags` - Transaction flags, e.g. marking the transaction as 249 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)). submit_transact( &self, code: TransactionCode, data: Parcel, flags: TransactionFlags, ) -> Result<Parcel>250 fn submit_transact( 251 &self, 252 code: TransactionCode, 253 data: Parcel, 254 flags: TransactionFlags, 255 ) -> Result<Parcel>; 256 257 /// Perform a generic operation with the object. This is a convenience 258 /// method that internally calls `prepare_transact` followed by 259 /// `submit_transact. 260 /// 261 /// # Arguments 262 /// * `code` - Transaction code for the operation 263 /// * `flags` - Transaction flags, e.g. marking the transaction as 264 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)) 265 /// * `input_callback` A callback for building the `Parcel`. transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>( &self, code: TransactionCode, flags: TransactionFlags, input_callback: F, ) -> Result<Parcel>266 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>( 267 &self, 268 code: TransactionCode, 269 flags: TransactionFlags, 270 input_callback: F, 271 ) -> Result<Parcel> { 272 let mut parcel = self.prepare_transact()?; 273 input_callback(parcel.borrowed())?; 274 self.submit_transact(code, parcel, flags) 275 } 276 } 277 278 /// Interface of binder local or remote objects. 279 /// 280 /// This trait corresponds to the parts of the interface of the C++ `IBinder` 281 /// class which are public. 282 pub trait IBinder { 283 /// Register the recipient for a notification if this binder 284 /// goes away. If this binder object unexpectedly goes away 285 /// (typically because its hosting process has been killed), 286 /// then the `DeathRecipient`'s callback will be called. 287 /// 288 /// You will only receive death notifications for remote binders, 289 /// as local binders by definition can't die without you dying as well. 290 /// Trying to use this function on a local binder will result in an 291 /// INVALID_OPERATION code being returned and nothing happening. 292 /// 293 /// This link only holds a weak reference to its recipient. If the 294 /// `DeathRecipient` is dropped then it will be unlinked. 295 /// 296 /// Note that the notifications won't work if you don't first start at least 297 /// one Binder thread by calling 298 /// [`ProcessState::start_thread_pool`](crate::ProcessState::start_thread_pool) 299 /// or 300 /// [`ProcessState::join_thread_pool`](crate::ProcessState::join_thread_pool). link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>301 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; 302 303 /// Remove a previously registered death notification. 304 /// The recipient will no longer be called if this object 305 /// dies. unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>306 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; 307 308 /// Send a ping transaction to this object ping_binder(&mut self) -> Result<()>309 fn ping_binder(&mut self) -> Result<()>; 310 } 311 312 /// Opaque reference to the type of a Binder interface. 313 /// 314 /// This object encapsulates the Binder interface descriptor string, along with 315 /// the binder transaction callback, if the class describes a local service. 316 /// 317 /// A Binder remotable object may only have a single interface class, and any 318 /// given object can only be associated with one class. Two objects with 319 /// different classes are incompatible, even if both classes have the same 320 /// interface descriptor. 321 #[derive(Copy, Clone, PartialEq, Eq)] 322 pub struct InterfaceClass(*const sys::AIBinder_Class); 323 324 impl InterfaceClass { 325 /// Get a Binder NDK `AIBinder_Class` pointer for this object type. 326 /// 327 /// Note: the returned pointer will not be constant. Calling this method 328 /// multiple times for the same type will result in distinct class 329 /// pointers. A static getter for this value is implemented in 330 /// [`crate::declare_binder_interface!`]. new<I: InterfaceClassMethods>() -> InterfaceClass331 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass { 332 let descriptor = CString::new(I::get_descriptor()).unwrap(); 333 // Safety: `AIBinder_Class_define` expects a valid C string, and three 334 // valid callback functions, all non-null pointers. The C string is 335 // copied and need not be valid for longer than the call, so we can drop 336 // it after the call. We can safely assign null to the onDump and 337 // handleShellCommand callbacks as long as the class pointer was 338 // non-null. Rust None for a Option<fn> is guaranteed to be a NULL 339 // pointer. Rust retains ownership of the pointer after it is defined. 340 let ptr = unsafe { 341 let class = sys::AIBinder_Class_define( 342 descriptor.as_ptr(), 343 Some(I::on_create), 344 Some(I::on_destroy), 345 Some(I::on_transact), 346 ); 347 if class.is_null() { 348 panic!("Expected non-null class pointer from AIBinder_Class_define!"); 349 } 350 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump)); 351 class 352 }; 353 InterfaceClass(ptr) 354 } 355 356 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class` 357 /// pointer. 358 /// 359 /// # Safety 360 /// 361 /// This function is safe iff `ptr` is a valid, non-null pointer to an 362 /// `AIBinder_Class`. from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass363 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass { 364 InterfaceClass(ptr) 365 } 366 367 /// Get the interface descriptor string of this class. get_descriptor(&self) -> String368 pub fn get_descriptor(&self) -> String { 369 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor is 370 // always a two-byte null terminated sequence of u16s. Thus, we can 371 // continue reading from the pointer until we hit a null value, and this 372 // pointer can be a valid slice if the slice length is <= the number of 373 // u16 elements before the null terminator. 374 unsafe { 375 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0); 376 CStr::from_ptr(raw_descriptor) 377 .to_str() 378 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor") 379 .into() 380 } 381 } 382 } 383 384 impl From<InterfaceClass> for *const sys::AIBinder_Class { from(class: InterfaceClass) -> *const sys::AIBinder_Class385 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class { 386 class.0 387 } 388 } 389 390 /// Strong reference to a binder object 391 pub struct Strong<I: FromIBinder + ?Sized>(Box<I>); 392 393 impl<I: FromIBinder + ?Sized> Strong<I> { 394 /// Create a new strong reference to the provided binder object new(binder: Box<I>) -> Self395 pub fn new(binder: Box<I>) -> Self { 396 Self(binder) 397 } 398 399 /// Construct a new weak reference to this binder downgrade(this: &Strong<I>) -> Weak<I>400 pub fn downgrade(this: &Strong<I>) -> Weak<I> { 401 Weak::new(this) 402 } 403 404 /// Convert this synchronous binder handle into an asynchronous one. into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target> where I: ToAsyncInterface<P>,405 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target> 406 where 407 I: ToAsyncInterface<P>, 408 { 409 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder 410 // object is also valid for the target type. 411 FromIBinder::try_from(self.0.as_binder()).unwrap() 412 } 413 414 /// Convert this asynchronous binder handle into a synchronous one. into_sync(self) -> Strong<<I as ToSyncInterface>::Target> where I: ToSyncInterface,415 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target> 416 where 417 I: ToSyncInterface, 418 { 419 // By implementing the ToSyncInterface trait, it is guaranteed that the binder 420 // object is also valid for the target type. 421 FromIBinder::try_from(self.0.as_binder()).unwrap() 422 } 423 } 424 425 impl<I: FromIBinder + ?Sized> Clone for Strong<I> { clone(&self) -> Self426 fn clone(&self) -> Self { 427 // Since we hold a strong reference, we should always be able to create 428 // a new strong reference to the same interface type, so try_from() 429 // should never fail here. 430 FromIBinder::try_from(self.0.as_binder()).unwrap() 431 } 432 } 433 434 impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> { borrow(&self) -> &I435 fn borrow(&self) -> &I { 436 &self.0 437 } 438 } 439 440 impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> { as_ref(&self) -> &I441 fn as_ref(&self) -> &I { 442 &self.0 443 } 444 } 445 446 impl<I: FromIBinder + ?Sized> Deref for Strong<I> { 447 type Target = I; 448 deref(&self) -> &Self::Target449 fn deref(&self) -> &Self::Target { 450 &self.0 451 } 452 } 453 454 impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result455 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 456 fmt::Debug::fmt(&**self, f) 457 } 458 } 459 460 impl<I: FromIBinder + ?Sized> Ord for Strong<I> { cmp(&self, other: &Self) -> Ordering461 fn cmp(&self, other: &Self) -> Ordering { 462 self.0.as_binder().cmp(&other.0.as_binder()) 463 } 464 } 465 466 impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> { partial_cmp(&self, other: &Self) -> Option<Ordering>467 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 468 Some(self.cmp(other)) 469 } 470 } 471 472 impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> { eq(&self, other: &Self) -> bool473 fn eq(&self, other: &Self) -> bool { 474 self.0.as_binder().eq(&other.0.as_binder()) 475 } 476 } 477 478 impl<I: FromIBinder + ?Sized> Eq for Strong<I> {} 479 480 /// Weak reference to a binder object 481 #[derive(Debug)] 482 pub struct Weak<I: FromIBinder + ?Sized> { 483 weak_binder: WpIBinder, 484 interface_type: PhantomData<I>, 485 } 486 487 impl<I: FromIBinder + ?Sized> Weak<I> { 488 /// Construct a new weak reference from a strong reference new(binder: &Strong<I>) -> Self489 fn new(binder: &Strong<I>) -> Self { 490 let weak_binder = binder.as_binder().downgrade(); 491 Weak { weak_binder, interface_type: PhantomData } 492 } 493 494 /// Upgrade this weak reference to a strong reference if the binder object 495 /// is still alive upgrade(&self) -> Result<Strong<I>>496 pub fn upgrade(&self) -> Result<Strong<I>> { 497 self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from) 498 } 499 } 500 501 impl<I: FromIBinder + ?Sized> Clone for Weak<I> { clone(&self) -> Self502 fn clone(&self) -> Self { 503 Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData } 504 } 505 } 506 507 impl<I: FromIBinder + ?Sized> Ord for Weak<I> { cmp(&self, other: &Self) -> Ordering508 fn cmp(&self, other: &Self) -> Ordering { 509 self.weak_binder.cmp(&other.weak_binder) 510 } 511 } 512 513 impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> { partial_cmp(&self, other: &Self) -> Option<Ordering>514 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 515 Some(self.cmp(other)) 516 } 517 } 518 519 impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> { eq(&self, other: &Self) -> bool520 fn eq(&self, other: &Self) -> bool { 521 self.weak_binder == other.weak_binder 522 } 523 } 524 525 impl<I: FromIBinder + ?Sized> Eq for Weak<I> {} 526 527 /// Create a function implementing a static getter for an interface class. 528 /// 529 /// Each binder interface (i.e. local [`Remotable`] service or remote proxy 530 /// [`Interface`]) must have global, static class that uniquely identifies 531 /// it. This macro implements an [`InterfaceClass`] getter to simplify these 532 /// implementations. 533 /// 534 /// The type of a structure that implements [`InterfaceClassMethods`] must be 535 /// passed to this macro. For local services, this should be `Binder<Self>` 536 /// since [`Binder`] implements [`InterfaceClassMethods`]. 537 /// 538 /// # Examples 539 /// 540 /// When implementing a local [`Remotable`] service `ExampleService`, the 541 /// `get_class` method is required in the [`Remotable`] impl block. This macro 542 /// should be used as follows to implement this functionality: 543 /// 544 /// ```rust 545 /// impl Remotable for ExampleService { 546 /// fn get_descriptor() -> &'static str { 547 /// "android.os.IExampleInterface" 548 /// } 549 /// 550 /// fn on_transact( 551 /// &self, 552 /// code: TransactionCode, 553 /// data: &BorrowedParcel, 554 /// reply: &mut BorrowedParcel, 555 /// ) -> Result<()> { 556 /// // ... 557 /// } 558 /// 559 /// binder_fn_get_class!(Binder<Self>); 560 /// } 561 /// ``` 562 macro_rules! binder_fn_get_class { 563 ($class:ty) => { 564 binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>()); 565 }; 566 567 ($constructor:expr) => { 568 fn get_class() -> $crate::binder_impl::InterfaceClass { 569 static CLASS_INIT: std::sync::Once = std::sync::Once::new(); 570 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; 571 572 // Safety: This assignment is guarded by the `CLASS_INIT` `Once` 573 // variable, and therefore is thread-safe, as it can only occur 574 // once. 575 CLASS_INIT.call_once(|| unsafe { 576 CLASS = Some($constructor); 577 }); 578 // Safety: The `CLASS` variable can only be mutated once, above, and 579 // is subsequently safe to read from any thread. 580 unsafe { CLASS.unwrap() } 581 } 582 }; 583 } 584 585 pub trait InterfaceClassMethods { 586 /// Get the interface descriptor string for this object type. get_descriptor() -> &'static str where Self: Sized587 fn get_descriptor() -> &'static str 588 where 589 Self: Sized; 590 591 /// Called during construction of a new `AIBinder` object of this interface 592 /// class. 593 /// 594 /// The opaque pointer parameter will be the parameter provided to 595 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new 596 /// `AIBinder` object. 597 /// 598 /// # Safety 599 /// 600 /// Callback called from C++. The parameter argument provided to 601 /// `AIBinder_new` must match the type expected here. The `AIBinder` object 602 /// will take ownership of the returned pointer, which it will free via 603 /// `on_destroy`. on_create(args: *mut c_void) -> *mut c_void604 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void; 605 606 /// Called when a transaction needs to be processed by the local service 607 /// implementation. 608 /// 609 /// # Safety 610 /// 611 /// Callback called from C++. The `binder` parameter must be a valid pointer 612 /// to a binder object of this class with userdata initialized via this 613 /// class's `on_create`. The parcel parameters must be valid pointers to 614 /// parcel objects. on_transact( binder: *mut sys::AIBinder, code: u32, data: *const sys::AParcel, reply: *mut sys::AParcel, ) -> status_t615 unsafe extern "C" fn on_transact( 616 binder: *mut sys::AIBinder, 617 code: u32, 618 data: *const sys::AParcel, 619 reply: *mut sys::AParcel, 620 ) -> status_t; 621 622 /// Called whenever an `AIBinder` object is no longer referenced and needs 623 /// to be destroyed. 624 /// 625 /// # Safety 626 /// 627 /// Callback called from C++. The opaque pointer parameter must be the value 628 /// returned by `on_create` for this class. This function takes ownership of 629 /// the provided pointer and destroys it. on_destroy(object: *mut c_void)630 unsafe extern "C" fn on_destroy(object: *mut c_void); 631 632 /// Called to handle the `dump` transaction. 633 /// 634 /// # Safety 635 /// 636 /// Must be called with a non-null, valid pointer to a local `AIBinder` that 637 /// contains a `T` pointer in its user data. fd should be a non-owned file 638 /// descriptor, and args must be an array of null-terminated string 639 /// poiinters with length num_args. on_dump( binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32, ) -> status_t640 unsafe extern "C" fn on_dump( 641 binder: *mut sys::AIBinder, 642 fd: i32, 643 args: *mut *const c_char, 644 num_args: u32, 645 ) -> status_t; 646 } 647 648 /// Interface for transforming a generic SpIBinder into a specific remote 649 /// interface trait. 650 /// 651 /// # Example 652 /// 653 /// For Binder interface `IFoo`, the following implementation should be made: 654 /// ```no_run 655 /// # use binder::{FromIBinder, SpIBinder, Result}; 656 /// # trait IFoo {} 657 /// impl FromIBinder for dyn IFoo { 658 /// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> { 659 /// // ... 660 /// # Err(binder::StatusCode::OK) 661 /// } 662 /// } 663 /// ``` 664 pub trait FromIBinder: Interface { 665 /// Try to interpret a generic Binder object as this interface. 666 /// 667 /// Returns a trait object for the `Self` interface if this object 668 /// implements that interface. try_from(ibinder: SpIBinder) -> Result<Strong<Self>>669 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>; 670 } 671 672 /// Trait for transparent Rust wrappers around android C++ native types. 673 /// 674 /// The pointer return by this trait's methods should be immediately passed to 675 /// C++ and not stored by Rust. The pointer is valid only as long as the 676 /// underlying C++ object is alive, so users must be careful to take this into 677 /// account, as Rust cannot enforce this. 678 /// 679 /// # Safety 680 /// 681 /// For this trait to be a correct implementation, `T` must be a valid android 682 /// C++ type. Since we cannot constrain this via the type system, this trait is 683 /// marked as unsafe. 684 pub unsafe trait AsNative<T> { 685 /// Return a pointer to the native version of `self` as_native(&self) -> *const T686 fn as_native(&self) -> *const T; 687 688 /// Return a mutable pointer to the native version of `self` as_native_mut(&mut self) -> *mut T689 fn as_native_mut(&mut self) -> *mut T; 690 } 691 692 // Safety: If V is a valid Android C++ type then we can either use that or a 693 // null pointer. 694 unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> { as_native(&self) -> *const T695 fn as_native(&self) -> *const T { 696 self.as_ref().map_or(ptr::null(), |v| v.as_native()) 697 } 698 as_native_mut(&mut self) -> *mut T699 fn as_native_mut(&mut self) -> *mut T { 700 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut()) 701 } 702 } 703 704 /// The features to enable when creating a native Binder. 705 /// 706 /// This should always be initialised with a default value, e.g.: 707 /// ``` 708 /// # use binder::BinderFeatures; 709 /// BinderFeatures { 710 /// set_requesting_sid: true, 711 /// ..BinderFeatures::default(), 712 /// } 713 /// ``` 714 #[derive(Clone, Debug, Default, Eq, PartialEq)] 715 pub struct BinderFeatures { 716 /// Indicates that the service intends to receive caller security contexts. This must be true 717 /// for `ThreadState::with_calling_sid` to work. 718 #[cfg(not(any(android_vndk, android_ndk)))] 719 pub set_requesting_sid: bool, 720 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility 721 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct 722 // expressions entirely. 723 #[doc(hidden)] 724 pub _non_exhaustive: (), 725 } 726 727 /// Declare typed interfaces for a binder object. 728 /// 729 /// Given an interface trait and descriptor string, create a native and remote 730 /// proxy wrapper for this interface. The native service object (`$native`) 731 /// implements `Remotable` and will dispatch to the function `$on_transact` to 732 /// handle transactions. The typed proxy object (`$proxy`) wraps remote binder 733 /// objects for this interface and can optionally contain additional fields. 734 /// 735 /// Assuming the interface trait is `Interface`, `$on_transact` function must 736 /// have the following type: 737 /// 738 /// ``` 739 /// # use binder::{Interface, TransactionCode, BorrowedParcel}; 740 /// # trait Placeholder { 741 /// fn on_transact( 742 /// service: &dyn Interface, 743 /// code: TransactionCode, 744 /// data: &BorrowedParcel, 745 /// reply: &mut BorrowedParcel, 746 /// ) -> binder::Result<()>; 747 /// # } 748 /// ``` 749 /// 750 /// # Examples 751 /// 752 /// The following example declares the local service type `BnServiceManager` and 753 /// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and 754 /// proxy respectively) for the `IServiceManager` Binder interface. The 755 /// interfaces will be identified by the descriptor string 756 /// "android.os.IServiceManager". The local service will dispatch transactions 757 /// using the provided function, `on_transact`. 758 /// 759 /// ``` 760 /// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel}; 761 /// 762 /// pub trait IServiceManager: Interface { 763 /// // remote methods... 764 /// } 765 /// 766 /// declare_binder_interface! { 767 /// IServiceManager["android.os.IServiceManager"] { 768 /// native: BnServiceManager(on_transact), 769 /// proxy: BpServiceManager, 770 /// } 771 /// } 772 /// 773 /// fn on_transact( 774 /// service: &dyn IServiceManager, 775 /// code: TransactionCode, 776 /// data: &BorrowedParcel, 777 /// reply: &mut BorrowedParcel, 778 /// ) -> binder::Result<()> { 779 /// // ... 780 /// Ok(()) 781 /// } 782 /// 783 /// impl IServiceManager for BpServiceManager { 784 /// // parceling/unparceling code for the IServiceManager emitted here 785 /// } 786 /// 787 /// impl IServiceManager for Binder<BnServiceManager> { 788 /// // Forward calls to local implementation 789 /// } 790 /// ``` 791 #[macro_export] 792 macro_rules! declare_binder_interface { 793 { 794 $interface:path[$descriptor:expr] { 795 native: $native:ident($on_transact:path), 796 proxy: $proxy:ident, 797 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)? 798 } 799 } => { 800 $crate::declare_binder_interface! { 801 $interface[$descriptor] { 802 native: $native($on_transact), 803 proxy: $proxy {}, 804 $(async: $async_interface $(($try_into_local_async))?,)? 805 stability: $crate::binder_impl::Stability::default(), 806 } 807 } 808 }; 809 810 { 811 $interface:path[$descriptor:expr] { 812 native: $native:ident($on_transact:path), 813 proxy: $proxy:ident, 814 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)? 815 stability: $stability:expr, 816 } 817 } => { 818 $crate::declare_binder_interface! { 819 $interface[$descriptor] { 820 native: $native($on_transact), 821 proxy: $proxy {}, 822 $(async: $async_interface $(($try_into_local_async))?,)? 823 stability: $stability, 824 } 825 } 826 }; 827 828 { 829 $interface:path[$descriptor:expr] { 830 native: $native:ident($on_transact:path), 831 proxy: $proxy:ident { 832 $($fname:ident: $fty:ty = $finit:expr),* 833 }, 834 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)? 835 } 836 } => { 837 $crate::declare_binder_interface! { 838 $interface[$descriptor] { 839 native: $native($on_transact), 840 proxy: $proxy { 841 $($fname: $fty = $finit),* 842 }, 843 $(async: $async_interface $(($try_into_local_async))?,)? 844 stability: $crate::binder_impl::Stability::default(), 845 } 846 } 847 }; 848 849 { 850 $interface:path[$descriptor:expr] { 851 native: $native:ident($on_transact:path), 852 proxy: $proxy:ident { 853 $($fname:ident: $fty:ty = $finit:expr),* 854 }, 855 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)? 856 stability: $stability:expr, 857 } 858 } => { 859 $crate::declare_binder_interface! { 860 $interface[$descriptor] { 861 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")] 862 native: $native($on_transact), 863 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] 864 proxy: $proxy { 865 $($fname: $fty = $finit),* 866 }, 867 $(async: $async_interface $(($try_into_local_async))?,)? 868 stability: $stability, 869 } 870 } 871 }; 872 873 { 874 $interface:path[$descriptor:expr] { 875 @doc[$native_doc:expr] 876 native: $native:ident($on_transact:path), 877 878 @doc[$proxy_doc:expr] 879 proxy: $proxy:ident { 880 $($fname:ident: $fty:ty = $finit:expr),* 881 }, 882 883 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)? 884 885 stability: $stability:expr, 886 } 887 } => { 888 #[doc = $proxy_doc] 889 pub struct $proxy { 890 binder: $crate::SpIBinder, 891 $($fname: $fty,)* 892 } 893 894 impl $crate::Interface for $proxy { 895 fn as_binder(&self) -> $crate::SpIBinder { 896 self.binder.clone() 897 } 898 } 899 900 impl $crate::binder_impl::Proxy for $proxy 901 where 902 $proxy: $interface, 903 { 904 fn get_descriptor() -> &'static str { 905 $descriptor 906 } 907 908 fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> { 909 Ok(Self { binder, $($fname: $finit),* }) 910 } 911 } 912 913 #[doc = $native_doc] 914 #[repr(transparent)] 915 pub struct $native(Box<dyn $interface + Sync + Send + 'static>); 916 917 impl $native { 918 /// Create a new binder service. 919 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { 920 #[cfg(not(android_ndk))] 921 let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability); 922 #[cfg(android_ndk)] 923 let mut binder = $crate::binder_impl::Binder::new($native(Box::new(inner))); 924 925 #[cfg(not(any(android_vndk, android_ndk)))] 926 $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); 927 $crate::Strong::new(Box::new(binder)) 928 } 929 930 /// Tries to downcast the interface to another type. 931 /// When receiving this object from a binder call, make sure that the object received is 932 /// a binder native object and that is of the right type for the Downcast: 933 /// 934 /// let binder = received_object.as_binder(); 935 /// if !binder.is_remote() { 936 /// let binder_native: Binder<BnFoo> = binder.try_into()?; 937 /// let original_object = binder_native.downcast_binder::<MyFoo>(); 938 /// // Check that returned type is not None before using it 939 /// } 940 /// 941 /// Handle the error cases instead of just calling `unwrap` or `expect` to prevent a 942 /// malicious caller to mount a Denial of Service attack. 943 pub fn downcast_binder<T: $interface>(&self) -> Option<&T> { 944 self.0.as_any().downcast_ref::<T>() 945 } 946 } 947 948 impl $crate::binder_impl::Remotable for $native { 949 fn get_descriptor() -> &'static str { 950 $descriptor 951 } 952 953 fn on_transact(&self, code: $crate::binder_impl::TransactionCode, data: &$crate::binder_impl::BorrowedParcel<'_>, reply: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 954 match $on_transact(&*self.0, code, data, reply) { 955 // The C++ backend converts UNEXPECTED_NULL into an exception 956 Err($crate::StatusCode::UNEXPECTED_NULL) => { 957 let status = $crate::Status::new_exception( 958 $crate::ExceptionCode::NULL_POINTER, 959 None, 960 ); 961 reply.write(&status) 962 }, 963 result => result 964 } 965 } 966 967 fn on_dump(&self, writer: &mut dyn std::io::Write, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> { 968 self.0.dump(writer, args) 969 } 970 971 fn get_class() -> $crate::binder_impl::InterfaceClass { 972 static CLASS_INIT: std::sync::Once = std::sync::Once::new(); 973 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; 974 975 // Safety: This assignment is guarded by the `CLASS_INIT` `Once` 976 // variable, and therefore is thread-safe, as it can only occur 977 // once. 978 CLASS_INIT.call_once(|| unsafe { 979 CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>()); 980 }); 981 // Safety: The `CLASS` variable can only be mutated once, above, 982 // and is subsequently safe to read from any thread. 983 unsafe { 984 CLASS.unwrap() 985 } 986 } 987 } 988 989 impl $crate::FromIBinder for dyn $interface { 990 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> { 991 use $crate::binder_impl::AssociateClass; 992 993 let existing_class = ibinder.get_class(); 994 if let Some(class) = existing_class { 995 if class != <$native as $crate::binder_impl::Remotable>::get_class() && 996 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() 997 { 998 // The binder object's descriptor string matches what we 999 // expect. We still need to treat this local or already 1000 // associated object as remote, because we can't cast it 1001 // into a Rust service object without a matching class 1002 // pointer. 1003 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); 1004 } 1005 } 1006 1007 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { 1008 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = 1009 std::convert::TryFrom::try_from(ibinder.clone()); 1010 if let Ok(service) = service { 1011 // We were able to associate with our expected class and 1012 // the service is local. 1013 return Ok($crate::Strong::new(Box::new(service))); 1014 } else { 1015 // Service is remote 1016 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); 1017 } 1018 } 1019 1020 Err($crate::StatusCode::BAD_TYPE.into()) 1021 } 1022 } 1023 1024 impl $crate::binder_impl::Serialize for dyn $interface + '_ 1025 where 1026 dyn $interface: $crate::Interface 1027 { 1028 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 1029 let binder = $crate::Interface::as_binder(self); 1030 parcel.write(&binder) 1031 } 1032 } 1033 1034 impl $crate::binder_impl::SerializeOption for dyn $interface + '_ { 1035 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 1036 parcel.write(&this.map($crate::Interface::as_binder)) 1037 } 1038 } 1039 1040 impl std::fmt::Debug for dyn $interface + '_ { 1041 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1042 f.pad(stringify!($interface)) 1043 } 1044 } 1045 1046 /// Convert a &dyn $interface to Strong<dyn $interface> 1047 impl std::borrow::ToOwned for dyn $interface { 1048 type Owned = $crate::Strong<dyn $interface>; 1049 fn to_owned(&self) -> Self::Owned { 1050 self.as_binder().into_interface() 1051 .expect(concat!("Error cloning interface ", stringify!($interface))) 1052 } 1053 } 1054 1055 $( 1056 // Async interface trait implementations. 1057 impl<P: $crate::BinderAsyncPool + 'static> $crate::FromIBinder for dyn $async_interface<P> { 1058 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> { 1059 use $crate::binder_impl::AssociateClass; 1060 1061 let existing_class = ibinder.get_class(); 1062 if let Some(class) = existing_class { 1063 if class != <$native as $crate::binder_impl::Remotable>::get_class() && 1064 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() 1065 { 1066 // The binder object's descriptor string matches what we 1067 // expect. We still need to treat this local or already 1068 // associated object as remote, because we can't cast it 1069 // into a Rust service object without a matching class 1070 // pointer. 1071 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); 1072 } 1073 } 1074 1075 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { 1076 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = 1077 std::convert::TryFrom::try_from(ibinder.clone()); 1078 $( 1079 // This part is only generated if the user of the macro specifies that the 1080 // trait has an `try_into_local_async` implementation. 1081 if let Ok(service) = service { 1082 if let Some(async_service) = $native::$try_into_local_async(service) { 1083 // We were able to associate with our expected class, 1084 // the service is local, and the local service is async. 1085 return Ok(async_service); 1086 } 1087 // The service is local but not async. Fall back to treating it as a 1088 // remote service. This means that calls to this local service have an 1089 // extra performance cost due to serialization, but async handle to 1090 // non-async server is considered a rare case, so this is okay. 1091 } 1092 )? 1093 // Treat service as remote. 1094 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); 1095 } 1096 1097 Err($crate::StatusCode::BAD_TYPE.into()) 1098 } 1099 } 1100 1101 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ { 1102 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 1103 let binder = $crate::Interface::as_binder(self); 1104 parcel.write(&binder) 1105 } 1106 } 1107 1108 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ { 1109 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 1110 parcel.write(&this.map($crate::Interface::as_binder)) 1111 } 1112 } 1113 1114 impl<P: $crate::BinderAsyncPool + 'static> std::fmt::Debug for dyn $async_interface<P> + '_ { 1115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1116 f.pad(stringify!($async_interface)) 1117 } 1118 } 1119 1120 /// Convert a &dyn $async_interface to Strong<dyn $async_interface> 1121 impl<P: $crate::BinderAsyncPool + 'static> std::borrow::ToOwned for dyn $async_interface<P> { 1122 type Owned = $crate::Strong<dyn $async_interface<P>>; 1123 fn to_owned(&self) -> Self::Owned { 1124 self.as_binder().into_interface() 1125 .expect(concat!("Error cloning interface ", stringify!($async_interface))) 1126 } 1127 } 1128 1129 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface { 1130 type Target = dyn $async_interface<P>; 1131 } 1132 1133 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> { 1134 type Target = dyn $interface; 1135 } 1136 )? 1137 }; 1138 } 1139 1140 /// Declare an AIDL enumeration. 1141 /// 1142 /// This is mainly used internally by the AIDL compiler. 1143 #[macro_export] 1144 macro_rules! declare_binder_enum { 1145 { 1146 $( #[$attr:meta] )* 1147 $enum:ident : [$backing:ty; $size:expr] { 1148 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )* 1149 } 1150 } => { 1151 $( #[$attr] )* 1152 #[derive(Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] 1153 #[allow(missing_docs)] 1154 pub struct $enum(pub $backing); 1155 impl $enum { 1156 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )* 1157 1158 #[inline(always)] 1159 #[allow(missing_docs)] 1160 pub const fn enum_values() -> [Self; $size] { 1161 [$(Self::$name),*] 1162 } 1163 } 1164 1165 impl std::fmt::Debug for $enum { 1166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1167 match self.0 { 1168 $($value => f.write_str(stringify!($name)),)* 1169 _ => f.write_fmt(format_args!("{}", self.0)) 1170 } 1171 } 1172 } 1173 1174 impl $crate::binder_impl::Serialize for $enum { 1175 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 1176 parcel.write(&self.0) 1177 } 1178 } 1179 1180 impl $crate::binder_impl::SerializeArray for $enum { 1181 fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 1182 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect(); 1183 <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel) 1184 } 1185 } 1186 1187 impl $crate::binder_impl::Deserialize for $enum { 1188 type UninitType = Self; 1189 fn uninit() -> Self::UninitType { Self::UninitType::default() } 1190 fn from_init(value: Self) -> Self::UninitType { value } 1191 1192 fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> { 1193 parcel.read().map(Self) 1194 } 1195 } 1196 1197 impl $crate::binder_impl::DeserializeArray for $enum { 1198 fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> { 1199 let v: Option<Vec<$backing>> = 1200 <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?; 1201 Ok(v.map(|v| v.into_iter().map(Self).collect())) 1202 } 1203 } 1204 }; 1205 } 1206