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::Parcel; 21 use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; 22 use crate::sys; 23 24 use std::borrow::Borrow; 25 use std::cmp::Ordering; 26 use std::ffi::{c_void, CStr, CString}; 27 use std::fmt; 28 use std::marker::PhantomData; 29 use std::ops::Deref; 30 use std::os::raw::c_char; 31 use std::os::unix::io::AsRawFd; 32 use std::ptr; 33 34 /// Binder action to perform. 35 /// 36 /// This must be a number between [`FIRST_CALL_TRANSACTION`] and 37 /// [`LAST_CALL_TRANSACTION`]. 38 pub type TransactionCode = u32; 39 40 /// Additional operation flags. 41 /// 42 /// `FLAG_*` values. 43 pub type TransactionFlags = u32; 44 45 /// Super-trait for Binder interfaces. 46 /// 47 /// This trait allows conversion of a Binder interface trait object into an 48 /// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL 49 /// interfaces) must implement this trait. 50 /// 51 /// This is equivalent `IInterface` in C++. 52 pub trait Interface: Send { 53 /// Convert this binder object into a generic [`SpIBinder`] reference. as_binder(&self) -> SpIBinder54 fn as_binder(&self) -> SpIBinder { 55 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.") 56 } 57 } 58 59 /// Interface stability promise 60 /// 61 /// An interface can promise to be a stable vendor interface ([`Vintf`]), or 62 /// makes no stability guarantees ([`Local`]). [`Local`] is 63 /// currently the default stability. 64 pub enum Stability { 65 /// Default stability, visible to other modules in the same compilation 66 /// context (e.g. modules on system.img) 67 Local, 68 69 /// A Vendor Interface Object, which promises to be stable 70 Vintf, 71 } 72 73 impl Default for Stability { default() -> Self74 fn default() -> Self { 75 Stability::Local 76 } 77 } 78 79 /// A local service that can be remotable via Binder. 80 /// 81 /// An object that implement this interface made be made into a Binder service 82 /// via `Binder::new(object)`. 83 /// 84 /// This is a low-level interface that should normally be automatically 85 /// generated from AIDL via the [`declare_binder_interface!`] macro. When using 86 /// the AIDL backend, users need only implement the high-level AIDL-defined 87 /// interface. The AIDL compiler then generates a container struct that wraps 88 /// the user-defined service and implements `Remotable`. 89 pub trait Remotable: Send + Sync { 90 /// The Binder interface descriptor string. 91 /// 92 /// This string is a unique identifier for a Binder interface, and should be 93 /// the same between all implementations of that interface. get_descriptor() -> &'static str94 fn get_descriptor() -> &'static str; 95 96 /// Handle and reply to a request to invoke a transaction on this object. 97 /// 98 /// `reply` may be [`None`] if the sender does not expect a reply. on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>99 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>; 100 101 /// Retrieve the class of this remote object. 102 /// 103 /// This method should always return the same InterfaceClass for the same 104 /// type. get_class() -> InterfaceClass105 fn get_class() -> InterfaceClass; 106 } 107 108 /// First transaction code available for user commands (inclusive) 109 pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION; 110 /// Last transaction code available for user commands (inclusive) 111 pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION; 112 113 /// Corresponds to TF_ONE_WAY -- an asynchronous call. 114 pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY; 115 /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made. 116 pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF; 117 /// Set to the vendor flag if we are building for the VNDK, 0 otherwise 118 pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL; 119 120 /// Internal interface of binder local or remote objects for making 121 /// transactions. 122 /// 123 /// This trait corresponds to the parts of the interface of the C++ `IBinder` 124 /// class which are internal implementation details. 125 pub trait IBinderInternal: IBinder { 126 /// Is this object still alive? is_binder_alive(&self) -> bool127 fn is_binder_alive(&self) -> bool; 128 129 /// Send a ping transaction to this object ping_binder(&mut self) -> Result<()>130 fn ping_binder(&mut self) -> Result<()>; 131 132 /// Indicate that the service intends to receive caller security contexts. set_requesting_sid(&mut self, enable: bool)133 fn set_requesting_sid(&mut self, enable: bool); 134 135 /// Dump this object to the given file handle dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>136 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>; 137 138 /// Get a new interface that exposes additional extension functionality, if 139 /// available. get_extension(&mut self) -> Result<Option<SpIBinder>>140 fn get_extension(&mut self) -> Result<Option<SpIBinder>>; 141 142 /// Perform a generic operation with the object. 143 /// 144 /// # Arguments 145 /// * `code` - Transaction code for the operation 146 /// * `data` - [`Parcel`] with input data 147 /// * `reply` - Optional [`Parcel`] for reply data 148 /// * `flags` - Transaction flags, e.g. marking the transaction as 149 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)) transact<F: FnOnce(&mut Parcel) -> Result<()>>( &self, code: TransactionCode, flags: TransactionFlags, input_callback: F, ) -> Result<Parcel>150 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>( 151 &self, 152 code: TransactionCode, 153 flags: TransactionFlags, 154 input_callback: F, 155 ) -> Result<Parcel>; 156 } 157 158 /// Interface of binder local or remote objects. 159 /// 160 /// This trait corresponds to the parts of the interface of the C++ `IBinder` 161 /// class which are public. 162 pub trait IBinder { 163 /// Register the recipient for a notification if this binder 164 /// goes away. If this binder object unexpectedly goes away 165 /// (typically because its hosting process has been killed), 166 /// then the `DeathRecipient`'s callback will be called. 167 /// 168 /// You will only receive death notifications for remote binders, 169 /// as local binders by definition can't die without you dying as well. 170 /// Trying to use this function on a local binder will result in an 171 /// INVALID_OPERATION code being returned and nothing happening. 172 /// 173 /// This link always holds a weak reference to its recipient. link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>174 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; 175 176 /// Remove a previously registered death notification. 177 /// The recipient will no longer be called if this object 178 /// dies. unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>179 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; 180 } 181 182 /// Opaque reference to the type of a Binder interface. 183 /// 184 /// This object encapsulates the Binder interface descriptor string, along with 185 /// the binder transaction callback, if the class describes a local service. 186 /// 187 /// A Binder remotable object may only have a single interface class, and any 188 /// given object can only be associated with one class. Two objects with 189 /// different classes are incompatible, even if both classes have the same 190 /// interface descriptor. 191 #[derive(Copy, Clone, PartialEq, Eq)] 192 pub struct InterfaceClass(*const sys::AIBinder_Class); 193 194 impl InterfaceClass { 195 /// Get a Binder NDK `AIBinder_Class` pointer for this object type. 196 /// 197 /// Note: the returned pointer will not be constant. Calling this method 198 /// multiple times for the same type will result in distinct class 199 /// pointers. A static getter for this value is implemented in 200 /// [`declare_binder_interface!`]. new<I: InterfaceClassMethods>() -> InterfaceClass201 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass { 202 let descriptor = CString::new(I::get_descriptor()).unwrap(); 203 let ptr = unsafe { 204 // Safety: `AIBinder_Class_define` expects a valid C string, and 205 // three valid callback functions, all non-null pointers. The C 206 // string is copied and need not be valid for longer than the call, 207 // so we can drop it after the call. We can safely assign null to 208 // the onDump and handleShellCommand callbacks as long as the class 209 // pointer was non-null. Rust None for a Option<fn> is guaranteed to 210 // be a NULL pointer. Rust retains ownership of the pointer after it 211 // is defined. 212 let class = sys::AIBinder_Class_define( 213 descriptor.as_ptr(), 214 Some(I::on_create), 215 Some(I::on_destroy), 216 Some(I::on_transact), 217 ); 218 if class.is_null() { 219 panic!("Expected non-null class pointer from AIBinder_Class_define!"); 220 } 221 sys::AIBinder_Class_setOnDump(class, None); 222 sys::AIBinder_Class_setHandleShellCommand(class, None); 223 class 224 }; 225 InterfaceClass(ptr) 226 } 227 228 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class` 229 /// pointer. 230 /// 231 /// # Safety 232 /// 233 /// This function is safe iff `ptr` is a valid, non-null pointer to an 234 /// `AIBinder_Class`. from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass235 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass { 236 InterfaceClass(ptr) 237 } 238 239 /// Get the interface descriptor string of this class. get_descriptor(&self) -> String240 pub fn get_descriptor(&self) -> String { 241 unsafe { 242 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor 243 // is always a two-byte null terminated sequence of u16s. Thus, we 244 // can continue reading from the pointer until we hit a null value, 245 // and this pointer can be a valid slice if the slice length is <= 246 // the number of u16 elements before the null terminator. 247 248 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0); 249 CStr::from_ptr(raw_descriptor) 250 .to_str() 251 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor") 252 .into() 253 } 254 } 255 } 256 257 impl From<InterfaceClass> for *const sys::AIBinder_Class { from(class: InterfaceClass) -> *const sys::AIBinder_Class258 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class { 259 class.0 260 } 261 } 262 263 /// Strong reference to a binder object 264 pub struct Strong<I: FromIBinder + ?Sized>(Box<I>); 265 266 impl<I: FromIBinder + ?Sized> Strong<I> { 267 /// Create a new strong reference to the provided binder object new(binder: Box<I>) -> Self268 pub fn new(binder: Box<I>) -> Self { 269 Self(binder) 270 } 271 272 /// Construct a new weak reference to this binder downgrade(this: &Strong<I>) -> Weak<I>273 pub fn downgrade(this: &Strong<I>) -> Weak<I> { 274 Weak::new(this) 275 } 276 } 277 278 impl<I: FromIBinder + ?Sized> Clone for Strong<I> { clone(&self) -> Self279 fn clone(&self) -> Self { 280 // Since we hold a strong reference, we should always be able to create 281 // a new strong reference to the same interface type, so try_from() 282 // should never fail here. 283 FromIBinder::try_from(self.0.as_binder()).unwrap() 284 } 285 } 286 287 impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> { borrow(&self) -> &I288 fn borrow(&self) -> &I { 289 &self.0 290 } 291 } 292 293 impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> { as_ref(&self) -> &I294 fn as_ref(&self) -> &I { 295 &self.0 296 } 297 } 298 299 impl<I: FromIBinder + ?Sized> Deref for Strong<I> { 300 type Target = I; 301 deref(&self) -> &Self::Target302 fn deref(&self) -> &Self::Target { 303 &self.0 304 } 305 } 306 307 impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result308 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 309 fmt::Debug::fmt(&**self, f) 310 } 311 } 312 313 impl<I: FromIBinder + ?Sized> Ord for Strong<I> { cmp(&self, other: &Self) -> Ordering314 fn cmp(&self, other: &Self) -> Ordering { 315 self.0.as_binder().cmp(&other.0.as_binder()) 316 } 317 } 318 319 impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> { partial_cmp(&self, other: &Self) -> Option<Ordering>320 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 321 self.0.as_binder().partial_cmp(&other.0.as_binder()) 322 } 323 } 324 325 impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> { eq(&self, other: &Self) -> bool326 fn eq(&self, other: &Self) -> bool { 327 self.0.as_binder().eq(&other.0.as_binder()) 328 } 329 } 330 331 impl<I: FromIBinder + ?Sized> Eq for Strong<I> {} 332 333 /// Weak reference to a binder object 334 #[derive(Debug)] 335 pub struct Weak<I: FromIBinder + ?Sized> { 336 weak_binder: WpIBinder, 337 interface_type: PhantomData<I>, 338 } 339 340 impl<I: FromIBinder + ?Sized> Weak<I> { 341 /// Construct a new weak reference from a strong reference new(binder: &Strong<I>) -> Self342 fn new(binder: &Strong<I>) -> Self { 343 let weak_binder = binder.as_binder().downgrade(); 344 Weak { 345 weak_binder, 346 interface_type: PhantomData, 347 } 348 } 349 350 /// Upgrade this weak reference to a strong reference if the binder object 351 /// is still alive upgrade(&self) -> Result<Strong<I>>352 pub fn upgrade(&self) -> Result<Strong<I>> { 353 self.weak_binder 354 .promote() 355 .ok_or(StatusCode::DEAD_OBJECT) 356 .and_then(FromIBinder::try_from) 357 } 358 } 359 360 impl<I: FromIBinder + ?Sized> Clone for Weak<I> { clone(&self) -> Self361 fn clone(&self) -> Self { 362 Self { 363 weak_binder: self.weak_binder.clone(), 364 interface_type: PhantomData, 365 } 366 } 367 } 368 369 impl<I: FromIBinder + ?Sized> Ord for Weak<I> { cmp(&self, other: &Self) -> Ordering370 fn cmp(&self, other: &Self) -> Ordering { 371 self.weak_binder.cmp(&other.weak_binder) 372 } 373 } 374 375 impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> { partial_cmp(&self, other: &Self) -> Option<Ordering>376 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 377 self.weak_binder.partial_cmp(&other.weak_binder) 378 } 379 } 380 381 impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> { eq(&self, other: &Self) -> bool382 fn eq(&self, other: &Self) -> bool { 383 self.weak_binder == other.weak_binder 384 } 385 } 386 387 impl<I: FromIBinder + ?Sized> Eq for Weak<I> {} 388 389 /// Create a function implementing a static getter for an interface class. 390 /// 391 /// Each binder interface (i.e. local [`Remotable`] service or remote proxy 392 /// [`Interface`]) must have global, static class that uniquely identifies 393 /// it. This macro implements an [`InterfaceClass`] getter to simplify these 394 /// implementations. 395 /// 396 /// The type of a structure that implements [`InterfaceClassMethods`] must be 397 /// passed to this macro. For local services, this should be `Binder<Self>` 398 /// since [`Binder`] implements [`InterfaceClassMethods`]. 399 /// 400 /// # Examples 401 /// 402 /// When implementing a local [`Remotable`] service `ExampleService`, the 403 /// `get_class` method is required in the [`Remotable`] impl block. This macro 404 /// should be used as follows to implement this functionality: 405 /// 406 /// ```rust 407 /// impl Remotable for ExampleService { 408 /// fn get_descriptor() -> &'static str { 409 /// "android.os.IExampleInterface" 410 /// } 411 /// 412 /// fn on_transact( 413 /// &self, 414 /// code: TransactionCode, 415 /// data: &Parcel, 416 /// reply: &mut Parcel, 417 /// ) -> Result<()> { 418 /// // ... 419 /// } 420 /// 421 /// binder_fn_get_class!(Binder<Self>); 422 /// } 423 /// ``` 424 macro_rules! binder_fn_get_class { 425 ($class:ty) => { 426 binder_fn_get_class!($crate::InterfaceClass::new::<$class>()); 427 }; 428 429 ($constructor:expr) => { 430 fn get_class() -> $crate::InterfaceClass { 431 static CLASS_INIT: std::sync::Once = std::sync::Once::new(); 432 static mut CLASS: Option<$crate::InterfaceClass> = None; 433 434 CLASS_INIT.call_once(|| unsafe { 435 // Safety: This assignment is guarded by the `CLASS_INIT` `Once` 436 // variable, and therefore is thread-safe, as it can only occur 437 // once. 438 CLASS = Some($constructor); 439 }); 440 unsafe { 441 // Safety: The `CLASS` variable can only be mutated once, above, 442 // and is subsequently safe to read from any thread. 443 CLASS.unwrap() 444 } 445 } 446 }; 447 } 448 449 pub trait InterfaceClassMethods { 450 /// Get the interface descriptor string for this object type. get_descriptor() -> &'static str where Self: Sized451 fn get_descriptor() -> &'static str 452 where 453 Self: Sized; 454 455 /// Called during construction of a new `AIBinder` object of this interface 456 /// class. 457 /// 458 /// The opaque pointer parameter will be the parameter provided to 459 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new 460 /// `AIBinder` object. 461 /// 462 /// # Safety 463 /// 464 /// Callback called from C++. The parameter argument provided to 465 /// `AIBinder_new` must match the type expected here. The `AIBinder` object 466 /// will take ownership of the returned pointer, which it will free via 467 /// `on_destroy`. on_create(args: *mut c_void) -> *mut c_void468 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void; 469 470 /// Called when a transaction needs to be processed by the local service 471 /// implementation. 472 /// 473 /// # Safety 474 /// 475 /// Callback called from C++. The `binder` parameter must be a valid pointer 476 /// to a binder object of this class with userdata initialized via this 477 /// class's `on_create`. The parcel parameters must be valid pointers to 478 /// parcel objects. on_transact( binder: *mut sys::AIBinder, code: u32, data: *const sys::AParcel, reply: *mut sys::AParcel, ) -> status_t479 unsafe extern "C" fn on_transact( 480 binder: *mut sys::AIBinder, 481 code: u32, 482 data: *const sys::AParcel, 483 reply: *mut sys::AParcel, 484 ) -> status_t; 485 486 /// Called whenever an `AIBinder` object is no longer referenced and needs 487 /// to be destroyed. 488 /// 489 /// # Safety 490 /// 491 /// Callback called from C++. The opaque pointer parameter must be the value 492 /// returned by `on_create` for this class. This function takes ownership of 493 /// the provided pointer and destroys it. on_destroy(object: *mut c_void)494 unsafe extern "C" fn on_destroy(object: *mut c_void); 495 } 496 497 /// Interface for transforming a generic SpIBinder into a specific remote 498 /// interface trait. 499 /// 500 /// # Example 501 /// 502 /// For Binder interface `IFoo`, the following implementation should be made: 503 /// ```no_run 504 /// # use binder::{FromIBinder, SpIBinder, Result}; 505 /// # trait IFoo {} 506 /// impl FromIBinder for dyn IFoo { 507 /// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> { 508 /// // ... 509 /// # Err(binder::StatusCode::OK) 510 /// } 511 /// } 512 /// ``` 513 pub trait FromIBinder: Interface { 514 /// Try to interpret a generic Binder object as this interface. 515 /// 516 /// Returns a trait object for the `Self` interface if this object 517 /// implements that interface. try_from(ibinder: SpIBinder) -> Result<Strong<Self>>518 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>; 519 } 520 521 /// Trait for transparent Rust wrappers around android C++ native types. 522 /// 523 /// The pointer return by this trait's methods should be immediately passed to 524 /// C++ and not stored by Rust. The pointer is valid only as long as the 525 /// underlying C++ object is alive, so users must be careful to take this into 526 /// account, as Rust cannot enforce this. 527 /// 528 /// # Safety 529 /// 530 /// For this trait to be a correct implementation, `T` must be a valid android 531 /// C++ type. Since we cannot constrain this via the type system, this trait is 532 /// marked as unsafe. 533 pub unsafe trait AsNative<T> { 534 /// Return a pointer to the native version of `self` as_native(&self) -> *const T535 fn as_native(&self) -> *const T; 536 537 /// Return a mutable pointer to the native version of `self` as_native_mut(&mut self) -> *mut T538 fn as_native_mut(&mut self) -> *mut T; 539 } 540 541 unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> { as_native(&self) -> *const T542 fn as_native(&self) -> *const T { 543 self.as_ref().map_or(ptr::null(), |v| v.as_native()) 544 } 545 as_native_mut(&mut self) -> *mut T546 fn as_native_mut(&mut self) -> *mut T { 547 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut()) 548 } 549 } 550 551 /// The features to enable when creating a native Binder. 552 /// 553 /// This should always be initialised with a default value, e.g.: 554 /// ``` 555 /// # use binder::BinderFeatures; 556 /// BinderFeatures { 557 /// set_requesting_sid: true, 558 /// ..BinderFeatures::default(), 559 /// } 560 /// ``` 561 #[derive(Clone, Debug, Default, Eq, PartialEq)] 562 pub struct BinderFeatures { 563 /// Indicates that the service intends to receive caller security contexts. This must be true 564 /// for `ThreadState::with_calling_sid` to work. 565 pub set_requesting_sid: bool, 566 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility 567 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct 568 // expressions entirely. 569 #[doc(hidden)] 570 pub _non_exhaustive: (), 571 } 572 573 /// Declare typed interfaces for a binder object. 574 /// 575 /// Given an interface trait and descriptor string, create a native and remote 576 /// proxy wrapper for this interface. The native service object (`$native`) 577 /// implements `Remotable` and will dispatch to the function `$on_transact` to 578 /// handle transactions. The typed proxy object (`$proxy`) wraps remote binder 579 /// objects for this interface and can optionally contain additional fields. 580 /// 581 /// Assuming the interface trait is `Interface`, `$on_transact` function must 582 /// have the following type: 583 /// 584 /// ``` 585 /// # use binder::{Interface, TransactionCode, Parcel}; 586 /// # trait Placeholder { 587 /// fn on_transact( 588 /// service: &dyn Interface, 589 /// code: TransactionCode, 590 /// data: &Parcel, 591 /// reply: &mut Parcel, 592 /// ) -> binder::Result<()>; 593 /// # } 594 /// ``` 595 /// 596 /// # Examples 597 /// 598 /// The following example declares the local service type `BnServiceManager` and 599 /// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and 600 /// proxy respectively) for the `IServiceManager` Binder interface. The 601 /// interfaces will be identified by the descriptor string 602 /// "android.os.IServiceManager". The local service will dispatch transactions 603 /// using the provided function, `on_transact`. 604 /// 605 /// ``` 606 /// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel}; 607 /// 608 /// pub trait IServiceManager: Interface { 609 /// // remote methods... 610 /// } 611 /// 612 /// declare_binder_interface! { 613 /// IServiceManager["android.os.IServiceManager"] { 614 /// native: BnServiceManager(on_transact), 615 /// proxy: BpServiceManager, 616 /// } 617 /// } 618 /// 619 /// fn on_transact( 620 /// service: &dyn IServiceManager, 621 /// code: TransactionCode, 622 /// data: &Parcel, 623 /// reply: &mut Parcel, 624 /// ) -> binder::Result<()> { 625 /// // ... 626 /// Ok(()) 627 /// } 628 /// 629 /// impl IServiceManager for BpServiceManager { 630 /// // parceling/unparceling code for the IServiceManager emitted here 631 /// } 632 /// 633 /// impl IServiceManager for Binder<BnServiceManager> { 634 /// // Forward calls to local implementation 635 /// } 636 /// ``` 637 #[macro_export] 638 macro_rules! declare_binder_interface { 639 { 640 $interface:path[$descriptor:expr] { 641 native: $native:ident($on_transact:path), 642 proxy: $proxy:ident, 643 } 644 } => { 645 $crate::declare_binder_interface! { 646 $interface[$descriptor] { 647 native: $native($on_transact), 648 proxy: $proxy {}, 649 stability: $crate::Stability::default(), 650 } 651 } 652 }; 653 654 { 655 $interface:path[$descriptor:expr] { 656 native: $native:ident($on_transact:path), 657 proxy: $proxy:ident, 658 stability: $stability:expr, 659 } 660 } => { 661 $crate::declare_binder_interface! { 662 $interface[$descriptor] { 663 native: $native($on_transact), 664 proxy: $proxy {}, 665 stability: $stability, 666 } 667 } 668 }; 669 670 { 671 $interface:path[$descriptor:expr] { 672 native: $native:ident($on_transact:path), 673 proxy: $proxy:ident { 674 $($fname:ident: $fty:ty = $finit:expr),* 675 }, 676 } 677 } => { 678 $crate::declare_binder_interface! { 679 $interface[$descriptor] { 680 native: $native($on_transact), 681 proxy: $proxy { 682 $($fname: $fty = $finit),* 683 }, 684 stability: $crate::Stability::default(), 685 } 686 } 687 }; 688 689 { 690 $interface:path[$descriptor:expr] { 691 native: $native:ident($on_transact:path), 692 proxy: $proxy:ident { 693 $($fname:ident: $fty:ty = $finit:expr),* 694 }, 695 stability: $stability:expr, 696 } 697 } => { 698 $crate::declare_binder_interface! { 699 $interface[$descriptor] { 700 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")] 701 native: $native($on_transact), 702 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] 703 proxy: $proxy { 704 $($fname: $fty = $finit),* 705 }, 706 stability: $stability, 707 } 708 } 709 }; 710 711 { 712 $interface:path[$descriptor:expr] { 713 @doc[$native_doc:expr] 714 native: $native:ident($on_transact:path), 715 716 @doc[$proxy_doc:expr] 717 proxy: $proxy:ident { 718 $($fname:ident: $fty:ty = $finit:expr),* 719 }, 720 721 stability: $stability:expr, 722 } 723 } => { 724 #[doc = $proxy_doc] 725 pub struct $proxy { 726 binder: $crate::SpIBinder, 727 $($fname: $fty,)* 728 } 729 730 impl $crate::Interface for $proxy { 731 fn as_binder(&self) -> $crate::SpIBinder { 732 self.binder.clone() 733 } 734 } 735 736 impl $crate::Proxy for $proxy 737 where 738 $proxy: $interface, 739 { 740 fn get_descriptor() -> &'static str { 741 $descriptor 742 } 743 744 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> { 745 Ok(Self { binder, $($fname: $finit),* }) 746 } 747 } 748 749 #[doc = $native_doc] 750 #[repr(transparent)] 751 pub struct $native(Box<dyn $interface + Sync + Send + 'static>); 752 753 impl $native { 754 /// Create a new binder service. 755 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { 756 let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability); 757 $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); 758 $crate::Strong::new(Box::new(binder)) 759 } 760 } 761 762 impl $crate::Remotable for $native { 763 fn get_descriptor() -> &'static str { 764 $descriptor 765 } 766 767 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> { 768 match $on_transact(&*self.0, code, data, reply) { 769 // The C++ backend converts UNEXPECTED_NULL into an exception 770 Err($crate::StatusCode::UNEXPECTED_NULL) => { 771 let status = $crate::Status::new_exception( 772 $crate::ExceptionCode::NULL_POINTER, 773 None, 774 ); 775 reply.write(&status) 776 }, 777 result => result 778 } 779 } 780 781 fn get_class() -> $crate::InterfaceClass { 782 static CLASS_INIT: std::sync::Once = std::sync::Once::new(); 783 static mut CLASS: Option<$crate::InterfaceClass> = None; 784 785 CLASS_INIT.call_once(|| unsafe { 786 // Safety: This assignment is guarded by the `CLASS_INIT` `Once` 787 // variable, and therefore is thread-safe, as it can only occur 788 // once. 789 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>()); 790 }); 791 unsafe { 792 // Safety: The `CLASS` variable can only be mutated once, above, 793 // and is subsequently safe to read from any thread. 794 CLASS.unwrap() 795 } 796 } 797 } 798 799 impl $crate::FromIBinder for dyn $interface { 800 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> { 801 use $crate::AssociateClass; 802 803 let existing_class = ibinder.get_class(); 804 if let Some(class) = existing_class { 805 if class != <$native as $crate::Remotable>::get_class() && 806 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor() 807 { 808 // The binder object's descriptor string matches what we 809 // expect. We still need to treat this local or already 810 // associated object as remote, because we can't cast it 811 // into a Rust service object without a matching class 812 // pointer. 813 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); 814 } 815 } 816 817 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) { 818 let service: $crate::Result<$crate::Binder<$native>> = 819 std::convert::TryFrom::try_from(ibinder.clone()); 820 if let Ok(service) = service { 821 // We were able to associate with our expected class and 822 // the service is local. 823 return Ok($crate::Strong::new(Box::new(service))); 824 } else { 825 // Service is remote 826 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); 827 } 828 } 829 830 Err($crate::StatusCode::BAD_TYPE.into()) 831 } 832 } 833 834 impl $crate::parcel::Serialize for dyn $interface + '_ 835 where 836 dyn $interface: $crate::Interface 837 { 838 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> { 839 let binder = $crate::Interface::as_binder(self); 840 parcel.write(&binder) 841 } 842 } 843 844 impl $crate::parcel::SerializeOption for dyn $interface + '_ { 845 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> { 846 parcel.write(&this.map($crate::Interface::as_binder)) 847 } 848 } 849 850 impl std::fmt::Debug for dyn $interface { 851 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 852 f.pad(stringify!($interface)) 853 } 854 } 855 856 /// Convert a &dyn $interface to Strong<dyn $interface> 857 impl std::borrow::ToOwned for dyn $interface { 858 type Owned = $crate::Strong<dyn $interface>; 859 fn to_owned(&self) -> Self::Owned { 860 self.as_binder().into_interface() 861 .expect(concat!("Error cloning interface ", stringify!($interface))) 862 } 863 } 864 }; 865 } 866 867 /// Declare an AIDL enumeration. 868 /// 869 /// This is mainly used internally by the AIDL compiler. 870 #[macro_export] 871 macro_rules! declare_binder_enum { 872 { 873 $enum:ident : $backing:ty { 874 $( $name:ident = $value:expr, )* 875 } 876 } => { 877 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] 878 pub struct $enum(pub $backing); 879 impl $enum { 880 $( pub const $name: Self = Self($value); )* 881 } 882 883 impl $crate::parcel::Serialize for $enum { 884 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> { 885 parcel.write(&self.0) 886 } 887 } 888 889 impl $crate::parcel::SerializeArray for $enum { 890 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> { 891 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect(); 892 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel) 893 } 894 } 895 896 impl $crate::parcel::Deserialize for $enum { 897 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> { 898 parcel.read().map(Self) 899 } 900 } 901 902 impl $crate::parcel::DeserializeArray for $enum { 903 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> { 904 let v: Option<Vec<$backing>> = 905 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?; 906 Ok(v.map(|v| v.into_iter().map(Self).collect())) 907 } 908 } 909 }; 910 } 911