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