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 //! Rust API for interacting with a remote binder service. 18 19 use crate::binder::{ 20 AsNative, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Strong, 21 TransactionCode, TransactionFlags, 22 }; 23 use crate::error::{status_result, Result, StatusCode}; 24 use crate::parcel::{ 25 BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, 26 SerializeArray, SerializeOption, 27 }; 28 use crate::sys; 29 30 use std::cmp::Ordering; 31 use std::convert::TryInto; 32 use std::ffi::{c_void, CString}; 33 use std::fmt; 34 use std::mem; 35 use std::os::fd::AsRawFd; 36 use std::ptr; 37 use std::sync::Arc; 38 39 /// A strong reference to a Binder remote object. 40 /// 41 /// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper 42 /// is untyped; typed interface access is implemented by the AIDL compiler. 43 pub struct SpIBinder(ptr::NonNull<sys::AIBinder>); 44 45 impl fmt::Debug for SpIBinder { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 47 f.pad("SpIBinder") 48 } 49 } 50 51 /// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is 52 /// thread-safe. 53 unsafe impl Send for SpIBinder {} 54 55 /// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is 56 /// thread-safe. 57 unsafe impl Sync for SpIBinder {} 58 59 impl SpIBinder { 60 /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer. 61 /// 62 /// # Safety 63 /// 64 /// This constructor is safe iff `ptr` is a null pointer or a valid pointer 65 /// to an `AIBinder`. 66 /// 67 /// In the non-null case, this method conceptually takes ownership of a strong 68 /// reference to the object, so `AIBinder_incStrong` must have been called 69 /// on the pointer before passing it to this constructor. This is generally 70 /// done by Binder NDK methods that return an `AIBinder`, but care should be 71 /// taken to ensure this invariant. 72 /// 73 /// All `SpIBinder` objects that are constructed will hold a valid pointer 74 /// to an `AIBinder`, which will remain valid for the entire lifetime of the 75 /// `SpIBinder` (we keep a strong reference, and only decrement on drop). from_raw(ptr: *mut sys::AIBinder) -> Option<Self>76 pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> { 77 ptr::NonNull::new(ptr).map(Self) 78 } 79 80 /// Extract a raw `AIBinder` pointer from this wrapper. 81 /// 82 /// This method should _only_ be used for testing. Do not try to use the NDK 83 /// interface directly for anything else. 84 /// 85 /// # Safety 86 /// 87 /// The resulting pointer is valid only as long as the SpIBinder is alive. 88 /// The SpIBinder object retains ownership of the AIBinder and the caller 89 /// should not attempt to free the returned pointer. as_raw(&self) -> *mut sys::AIBinder90 pub unsafe fn as_raw(&self) -> *mut sys::AIBinder { 91 self.0.as_ptr() 92 } 93 94 /// Return true if this binder object is hosted in a different process than 95 /// the current one. is_remote(&self) -> bool96 pub fn is_remote(&self) -> bool { 97 // Safety: `SpIBinder` guarantees that it always contains a valid 98 // `AIBinder` pointer. 99 unsafe { sys::AIBinder_isRemote(self.as_native()) } 100 } 101 102 /// Try to convert this Binder object into a trait object for the given 103 /// Binder interface. 104 /// 105 /// If this object does not implement the expected interface, the error 106 /// `StatusCode::BAD_TYPE` is returned. into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>>107 pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> { 108 FromIBinder::try_from(self) 109 } 110 111 /// Return the interface class of this binder object, if associated with 112 /// one. get_class(&mut self) -> Option<InterfaceClass>113 pub fn get_class(&mut self) -> Option<InterfaceClass> { 114 // Safety: `SpIBinder` guarantees that it always contains a valid 115 // `AIBinder` pointer. `AIBinder_getClass` returns either a null 116 // pointer or a valid pointer to an `AIBinder_Class`. After mapping 117 // null to None, we can safely construct an `InterfaceClass` if the 118 // pointer was non-null. 119 unsafe { 120 let class = sys::AIBinder_getClass(self.as_native_mut()); 121 class.as_ref().map(|p| InterfaceClass::from_ptr(p)) 122 } 123 } 124 125 /// Creates a new weak reference to this binder object. downgrade(&mut self) -> WpIBinder126 pub fn downgrade(&mut self) -> WpIBinder { 127 WpIBinder::new(self) 128 } 129 } 130 131 pub mod unstable_api { 132 use super::{sys, SpIBinder}; 133 134 /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is 135 /// needed to bridge RPC binder, which doesn't have Rust API yet. 136 /// TODO(b/184872979): remove once the Rust API is created. 137 /// 138 /// # Safety 139 /// 140 /// See `SpIBinder::from_raw`. new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder>141 pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> { 142 // Safety: The caller makes the same guarantees as this requires. 143 unsafe { SpIBinder::from_raw(ptr) } 144 } 145 } 146 147 /// An object that can be associate with an [`InterfaceClass`]. 148 pub trait AssociateClass { 149 /// Check if this object is a valid object for the given interface class 150 /// `I`. 151 /// 152 /// Returns `Some(self)` if this is a valid instance of the interface, and 153 /// `None` otherwise. 154 /// 155 /// Classes constructed by `InterfaceClass` are unique per type, so 156 /// repeatedly calling this method for the same `InterfaceClass` is allowed. associate_class(&mut self, class: InterfaceClass) -> bool157 fn associate_class(&mut self, class: InterfaceClass) -> bool; 158 } 159 160 impl AssociateClass for SpIBinder { associate_class(&mut self, class: InterfaceClass) -> bool161 fn associate_class(&mut self, class: InterfaceClass) -> bool { 162 // Safety: `SpIBinder` guarantees that it always contains a valid 163 // `AIBinder` pointer. An `InterfaceClass` can always be converted 164 // into a valid `AIBinder_Class` pointer, so these parameters are 165 // always safe. 166 unsafe { sys::AIBinder_associateClass(self.as_native_mut(), class.into()) } 167 } 168 } 169 170 impl Ord for SpIBinder { cmp(&self, other: &Self) -> Ordering171 fn cmp(&self, other: &Self) -> Ordering { 172 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so this 173 // pointer is always safe to pass to `AIBinder_lt` (null is also safe to 174 // pass to this function, but we should never do that). 175 let less_than = unsafe { sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr()) }; 176 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so this 177 // pointer is always safe to pass to `AIBinder_lt` (null is also safe to 178 // pass to this function, but we should never do that). 179 let greater_than = unsafe { sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr()) }; 180 if !less_than && !greater_than { 181 Ordering::Equal 182 } else if less_than { 183 Ordering::Less 184 } else { 185 Ordering::Greater 186 } 187 } 188 } 189 190 impl PartialOrd for SpIBinder { partial_cmp(&self, other: &Self) -> Option<Ordering>191 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 192 Some(self.cmp(other)) 193 } 194 } 195 196 impl PartialEq for SpIBinder { eq(&self, other: &Self) -> bool197 fn eq(&self, other: &Self) -> bool { 198 ptr::eq(self.0.as_ptr(), other.0.as_ptr()) 199 } 200 } 201 202 impl Eq for SpIBinder {} 203 204 impl Clone for SpIBinder { clone(&self) -> Self205 fn clone(&self) -> Self { 206 // Safety: Cloning a strong reference must increment the reference 207 // count. We are guaranteed by the `SpIBinder` constructor 208 // invariants that `self.0` is always a valid `AIBinder` pointer. 209 unsafe { 210 sys::AIBinder_incStrong(self.0.as_ptr()); 211 } 212 Self(self.0) 213 } 214 } 215 216 impl Drop for SpIBinder { 217 // We hold a strong reference to the IBinder in SpIBinder and need to give up 218 // this reference on drop. drop(&mut self)219 fn drop(&mut self) { 220 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we 221 // know this pointer is safe to pass to `AIBinder_decStrong` here. 222 unsafe { 223 sys::AIBinder_decStrong(self.as_native_mut()); 224 } 225 } 226 } 227 228 impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { prepare_transact(&self) -> Result<Parcel>229 fn prepare_transact(&self) -> Result<Parcel> { 230 let mut input = ptr::null_mut(); 231 // Safety: `SpIBinder` guarantees that `self` always contains a 232 // valid pointer to an `AIBinder`. It is safe to cast from an 233 // immutable pointer to a mutable pointer here, because 234 // `AIBinder_prepareTransaction` only calls immutable `AIBinder` 235 // methods but the parameter is unfortunately not marked as const. 236 // 237 // After the call, input will be either a valid, owned `AParcel` 238 // pointer, or null. 239 let status = unsafe { 240 sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input) 241 }; 242 243 status_result(status)?; 244 245 // Safety: At this point, `input` is either a valid, owned `AParcel` 246 // pointer, or null. `OwnedParcel::from_raw` safely handles both cases, 247 // taking ownership of the parcel. 248 unsafe { Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL) } 249 } 250 submit_transact( &self, code: TransactionCode, data: Parcel, flags: TransactionFlags, ) -> Result<Parcel>251 fn submit_transact( 252 &self, 253 code: TransactionCode, 254 data: Parcel, 255 flags: TransactionFlags, 256 ) -> Result<Parcel> { 257 let mut reply = ptr::null_mut(); 258 // Safety: `SpIBinder` guarantees that `self` always contains a 259 // valid pointer to an `AIBinder`. Although `IBinder::transact` is 260 // not a const method, it is still safe to cast our immutable 261 // pointer to mutable for the call. First, `IBinder::transact` is 262 // thread-safe, so concurrency is not an issue. The only way that 263 // `transact` can affect any visible, mutable state in the current 264 // process is by calling `onTransact` for a local service. However, 265 // in order for transactions to be thread-safe, this method must 266 // dynamically lock its data before modifying it. We enforce this 267 // property in Rust by requiring `Sync` for remotable objects and 268 // only providing `on_transact` with an immutable reference to 269 // `self`. 270 // 271 // This call takes ownership of the `data` parcel pointer, and 272 // passes ownership of the `reply` out parameter to its caller. It 273 // does not affect ownership of the `binder` parameter. 274 let status = unsafe { 275 sys::AIBinder_transact( 276 self.as_native() as *mut sys::AIBinder, 277 code, 278 &mut data.into_raw(), 279 &mut reply, 280 flags, 281 ) 282 }; 283 status_result(status)?; 284 285 // Safety: `reply` is either a valid `AParcel` pointer or null 286 // after the call to `AIBinder_transact` above, so we can 287 // construct a `Parcel` out of it. `AIBinder_transact` passes 288 // ownership of the `reply` parcel to Rust, so we need to 289 // construct an owned variant. 290 unsafe { Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL) } 291 } 292 is_binder_alive(&self) -> bool293 fn is_binder_alive(&self) -> bool { 294 // Safety: `SpIBinder` guarantees that `self` always contains a valid 295 // pointer to an `AIBinder`. 296 // 297 // This call does not affect ownership of its pointer parameter. 298 unsafe { sys::AIBinder_isAlive(self.as_native()) } 299 } 300 301 #[cfg(not(android_vndk))] set_requesting_sid(&mut self, enable: bool)302 fn set_requesting_sid(&mut self, enable: bool) { 303 // Safety: `SpIBinder` guarantees that `self` always contains a valid 304 // pointer to an `AIBinder`. 305 // 306 // This call does not affect ownership of its pointer parameter. 307 unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) }; 308 } 309 dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>310 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> { 311 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect(); 312 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect(); 313 // Safety: `SpIBinder` guarantees that `self` always contains a 314 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the 315 // file descriptor parameter is always be a valid open file. The 316 // `args` pointer parameter is a valid pointer to an array of C 317 // strings that will outlive the call since `args` lives for the 318 // whole function scope. 319 // 320 // This call does not affect ownership of its binder pointer 321 // parameter and does not take ownership of the file or args array 322 // parameters. 323 let status = unsafe { 324 sys::AIBinder_dump( 325 self.as_native_mut(), 326 fp.as_raw_fd(), 327 arg_ptrs.as_mut_ptr(), 328 arg_ptrs.len().try_into().unwrap(), 329 ) 330 }; 331 status_result(status) 332 } 333 get_extension(&mut self) -> Result<Option<SpIBinder>>334 fn get_extension(&mut self) -> Result<Option<SpIBinder>> { 335 let mut out = ptr::null_mut(); 336 // Safety: `SpIBinder` guarantees that `self` always contains a 337 // valid pointer to an `AIBinder`. After this call, the `out` 338 // parameter will be either null, or a valid pointer to an 339 // `AIBinder`. 340 // 341 // This call passes ownership of the out pointer to its caller 342 // (assuming it is set to a non-null value). 343 let status = unsafe { sys::AIBinder_getExtension(self.as_native_mut(), &mut out) }; 344 // Safety: The call above guarantees that `out` is either null or a 345 // valid, owned pointer to an `AIBinder`, both of which are safe to 346 // pass to `SpIBinder::from_raw`. 347 let ibinder = unsafe { SpIBinder::from_raw(out) }; 348 349 status_result(status)?; 350 Ok(ibinder) 351 } 352 } 353 354 impl<T: AsNative<sys::AIBinder>> IBinder for T { link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>355 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> { 356 // Safety: `SpIBinder` guarantees that `self` always contains a 357 // valid pointer to an `AIBinder`. `recipient` can always be 358 // converted into a valid pointer to an 359 // `AIBinder_DeathRecipient`. 360 // 361 // The cookie is also the correct pointer, and by calling new_cookie, 362 // we have created a new ref-count to the cookie, which linkToDeath 363 // takes ownership of. Once the DeathRecipient is unlinked for any 364 // reason (including if this call fails), the onUnlinked callback 365 // will consume that ref-count. 366 status_result(unsafe { 367 sys::AIBinder_linkToDeath( 368 self.as_native_mut(), 369 recipient.as_native_mut(), 370 recipient.new_cookie(), 371 ) 372 }) 373 } 374 unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>375 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> { 376 // Safety: `SpIBinder` guarantees that `self` always contains a 377 // valid pointer to an `AIBinder`. `recipient` can always be 378 // converted into a valid pointer to an 379 // `AIBinder_DeathRecipient`. Any value is safe to pass as the 380 // cookie, although we depend on this value being set by 381 // `get_cookie` when the death recipient callback is called. 382 status_result(unsafe { 383 sys::AIBinder_unlinkToDeath( 384 self.as_native_mut(), 385 recipient.as_native_mut(), 386 recipient.get_cookie(), 387 ) 388 }) 389 } 390 ping_binder(&mut self) -> Result<()>391 fn ping_binder(&mut self) -> Result<()> { 392 // Safety: `SpIBinder` guarantees that `self` always contains a 393 // valid pointer to an `AIBinder`. 394 // 395 // This call does not affect ownership of its pointer parameter. 396 let status = unsafe { sys::AIBinder_ping(self.as_native_mut()) }; 397 status_result(status) 398 } 399 } 400 401 impl Serialize for SpIBinder { serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>402 fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> { 403 parcel.write_binder(Some(self)) 404 } 405 } 406 407 impl SerializeOption for SpIBinder { serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()>408 fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> { 409 parcel.write_binder(this) 410 } 411 } 412 413 impl SerializeArray for SpIBinder {} 414 415 impl Deserialize for SpIBinder { 416 type UninitType = Option<Self>; uninit() -> Self::UninitType417 fn uninit() -> Self::UninitType { 418 Self::UninitType::default() 419 } from_init(value: Self) -> Self::UninitType420 fn from_init(value: Self) -> Self::UninitType { 421 Some(value) 422 } 423 deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder>424 fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> { 425 parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL)) 426 } 427 } 428 429 impl DeserializeOption for SpIBinder { deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>>430 fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> { 431 parcel.read_binder() 432 } 433 } 434 435 impl DeserializeArray for SpIBinder {} 436 437 /// A weak reference to a Binder remote object. 438 /// 439 /// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper 440 /// is untyped; typed interface access is implemented by the AIDL compiler. 441 pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>); 442 443 impl fmt::Debug for WpIBinder { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 445 f.pad("WpIBinder") 446 } 447 } 448 449 /// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is 450 /// thread-safe. 451 unsafe impl Send for WpIBinder {} 452 453 /// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is 454 /// thread-safe. 455 unsafe impl Sync for WpIBinder {} 456 457 impl WpIBinder { 458 /// Create a new weak reference from an object that can be converted into a 459 /// raw `AIBinder` pointer. new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder460 fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder { 461 // Safety: `SpIBinder` guarantees that `binder` always contains a valid 462 // pointer to an `AIBinder`. 463 let ptr = unsafe { sys::AIBinder_Weak_new(binder.as_native_mut()) }; 464 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new")) 465 } 466 467 /// Promote this weak reference to a strong reference to the binder object. promote(&self) -> Option<SpIBinder>468 pub fn promote(&self) -> Option<SpIBinder> { 469 // Safety: `WpIBinder` always contains a valid weak reference, so we can 470 // pass this pointer to `AIBinder_Weak_promote`. Returns either null or 471 // an AIBinder owned by the caller, both of which are valid to pass to 472 // `SpIBinder::from_raw`. 473 unsafe { 474 let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr()); 475 SpIBinder::from_raw(ptr) 476 } 477 } 478 } 479 480 impl Clone for WpIBinder { clone(&self) -> Self481 fn clone(&self) -> Self { 482 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so 483 // this pointer is always safe to pass to `AIBinder_Weak_clone` 484 // (although null is also a safe value to pass to this API). 485 // 486 // We get ownership of the returned pointer, so can construct a new 487 // WpIBinder object from it. 488 let ptr = unsafe { sys::AIBinder_Weak_clone(self.0.as_ptr()) }; 489 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone")) 490 } 491 } 492 493 impl Ord for WpIBinder { cmp(&self, other: &Self) -> Ordering494 fn cmp(&self, other: &Self) -> Ordering { 495 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so 496 // this pointer is always safe to pass to `AIBinder_Weak_lt` (null is 497 // also safe to pass to this function, but we should never do that). 498 let less_than = unsafe { sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr()) }; 499 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so 500 // this pointer is always safe to pass to `AIBinder_Weak_lt` (null is 501 // also safe to pass to this function, but we should never do that). 502 let greater_than = unsafe { sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr()) }; 503 if !less_than && !greater_than { 504 Ordering::Equal 505 } else if less_than { 506 Ordering::Less 507 } else { 508 Ordering::Greater 509 } 510 } 511 } 512 513 impl PartialOrd for WpIBinder { 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 PartialEq for WpIBinder { eq(&self, other: &Self) -> bool520 fn eq(&self, other: &Self) -> bool { 521 self.cmp(other) == Ordering::Equal 522 } 523 } 524 525 impl Eq for WpIBinder {} 526 527 impl Drop for WpIBinder { drop(&mut self)528 fn drop(&mut self) { 529 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we 530 // know this pointer is safe to pass to `AIBinder_Weak_delete` here. 531 unsafe { 532 sys::AIBinder_Weak_delete(self.0.as_ptr()); 533 } 534 } 535 } 536 537 /// Rust wrapper around DeathRecipient objects. 538 /// 539 /// The cookie in this struct represents an `Arc<F>` for the owned callback. 540 /// This struct owns a ref-count of it, and so does every binder that we 541 /// have been linked with. 542 /// 543 /// Dropping the `DeathRecipient` will `unlink_to_death` any binders it is 544 /// currently linked to. 545 #[repr(C)] 546 pub struct DeathRecipient { 547 recipient: *mut sys::AIBinder_DeathRecipient, 548 cookie: *mut c_void, 549 vtable: &'static DeathRecipientVtable, 550 } 551 552 struct DeathRecipientVtable { 553 cookie_incr_refcount: unsafe extern "C" fn(*mut c_void), 554 cookie_decr_refcount: unsafe extern "C" fn(*mut c_void), 555 } 556 557 /// Safety: A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and 558 /// a pointer to a `Fn` which is `Sync` and `Send` (the cookie field). As 559 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too. 560 unsafe impl Send for DeathRecipient {} 561 562 /// Safety: A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and 563 /// a pointer to a `Fn` which is `Sync` and `Send` (the cookie field). As 564 /// `AIBinder_DeathRecipient` is threadsafe, this structure is too. 565 unsafe impl Sync for DeathRecipient {} 566 567 impl DeathRecipient { 568 /// Create a new death recipient that will call the given callback when its 569 /// associated object dies. new<F>(callback: F) -> DeathRecipient where F: Fn() + Send + Sync + 'static,570 pub fn new<F>(callback: F) -> DeathRecipient 571 where 572 F: Fn() + Send + Sync + 'static, 573 { 574 let callback: *const F = Arc::into_raw(Arc::new(callback)); 575 // Safety: The function pointer is a valid death recipient callback. 576 // 577 // This call returns an owned `AIBinder_DeathRecipient` pointer which 578 // must be destroyed via `AIBinder_DeathRecipient_delete` when no longer 579 // needed. 580 let recipient = unsafe { sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>)) }; 581 // Safety: The function pointer is a valid onUnlinked callback. 582 // 583 // All uses of linkToDeath in this file correctly increment the 584 // ref-count that this onUnlinked callback will decrement. 585 unsafe { 586 sys::AIBinder_DeathRecipient_setOnUnlinked( 587 recipient, 588 Some(Self::cookie_decr_refcount::<F>), 589 ); 590 } 591 DeathRecipient { 592 recipient, 593 cookie: callback as *mut c_void, 594 vtable: &DeathRecipientVtable { 595 cookie_incr_refcount: Self::cookie_incr_refcount::<F>, 596 cookie_decr_refcount: Self::cookie_decr_refcount::<F>, 597 }, 598 } 599 } 600 601 /// Increment the ref-count for the cookie and return it. 602 /// 603 /// # Safety 604 /// 605 /// The caller must handle the returned ref-count correctly. new_cookie(&self) -> *mut c_void606 unsafe fn new_cookie(&self) -> *mut c_void { 607 // Safety: `cookie_incr_refcount` points to 608 // `Self::cookie_incr_refcount`, and `self.cookie` is the cookie for an 609 // Arc<F>. 610 unsafe { 611 (self.vtable.cookie_incr_refcount)(self.cookie); 612 } 613 614 // Return a raw pointer with ownership of a ref-count 615 self.cookie 616 } 617 618 /// Get the opaque cookie that identifies this death recipient. 619 /// 620 /// This cookie will be used to link and unlink this death recipient to a 621 /// binder object and will be passed to the `binder_died` callback as an 622 /// opaque userdata pointer. get_cookie(&self) -> *mut c_void623 fn get_cookie(&self) -> *mut c_void { 624 self.cookie 625 } 626 627 /// Callback invoked from C++ when the binder object dies. 628 /// 629 /// # Safety 630 /// 631 /// The `cookie` parameter must be the cookie for an `Arc<F>` and 632 /// the caller must hold a ref-count to it. binder_died<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,633 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void) 634 where 635 F: Fn() + Send + Sync + 'static, 636 { 637 // Safety: The caller promises that `cookie` is for an Arc<F>. 638 let callback = unsafe { (cookie as *const F).as_ref().unwrap() }; 639 callback(); 640 } 641 642 /// Callback that decrements the ref-count. 643 /// This is invoked from C++ when a binder is unlinked. 644 /// 645 /// # Safety 646 /// 647 /// The `cookie` parameter must be the cookie for an `Arc<F>` and 648 /// the owner must give up a ref-count to it. cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,649 unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void) 650 where 651 F: Fn() + Send + Sync + 'static, 652 { 653 // Safety: The caller promises that `cookie` is for an Arc<F>. 654 drop(unsafe { Arc::from_raw(cookie as *const F) }); 655 } 656 657 /// Callback that increments the ref-count. 658 /// 659 /// # Safety 660 /// 661 /// The `cookie` parameter must be the cookie for an `Arc<F>` and 662 /// the owner must handle the created ref-count properly. cookie_incr_refcount<F>(cookie: *mut c_void) where F: Fn() + Send + Sync + 'static,663 unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void) 664 where 665 F: Fn() + Send + Sync + 'static, 666 { 667 // Safety: The caller promises that `cookie` is for an Arc<F>. 668 let arc = mem::ManuallyDrop::new(unsafe { Arc::from_raw(cookie as *const F) }); 669 mem::forget(Arc::clone(&arc)); 670 } 671 } 672 673 /// Safety: A `DeathRecipient` is always constructed with a valid raw pointer to 674 /// an `AIBinder_DeathRecipient`, so it is always type-safe to extract this 675 /// pointer. 676 unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient { as_native(&self) -> *const sys::AIBinder_DeathRecipient677 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient { 678 self.recipient 679 } 680 as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient681 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient { 682 self.recipient 683 } 684 } 685 686 impl Drop for DeathRecipient { drop(&mut self)687 fn drop(&mut self) { 688 // Safety: `self.recipient` is always a valid, owned 689 // `AIBinder_DeathRecipient` pointer returned by 690 // `AIBinder_DeathRecipient_new` when `self` was created. This delete 691 // method can only be called once when `self` is dropped. 692 unsafe { 693 sys::AIBinder_DeathRecipient_delete(self.recipient); 694 } 695 696 // Safety: We own a ref-count to the cookie, and so does every linked 697 // binder. This call gives up our ref-count. The linked binders should 698 // already have given up their ref-count, or should do so shortly. 699 unsafe { 700 (self.vtable.cookie_decr_refcount)(self.cookie); 701 } 702 } 703 } 704 705 /// Generic interface to remote binder objects. 706 /// 707 /// Corresponds to the C++ `BpInterface` class. 708 pub trait Proxy: Sized + Interface { 709 /// The Binder interface descriptor string. 710 /// 711 /// This string is a unique identifier for a Binder interface, and should be 712 /// the same between all implementations of that interface. get_descriptor() -> &'static str713 fn get_descriptor() -> &'static str; 714 715 /// Create a new interface from the given proxy, if it matches the expected 716 /// type of this interface. from_binder(binder: SpIBinder) -> Result<Self>717 fn from_binder(binder: SpIBinder) -> Result<Self>; 718 } 719 720 /// Safety: This is a convenience method that wraps `AsNative` for `SpIBinder` 721 /// to allow invocation of `IBinder` methods directly from `Interface` objects. 722 /// It shares the same safety as the implementation for `SpIBinder`. 723 unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T { as_native(&self) -> *const sys::AIBinder724 fn as_native(&self) -> *const sys::AIBinder { 725 self.as_binder().as_native() 726 } 727 as_native_mut(&mut self) -> *mut sys::AIBinder728 fn as_native_mut(&mut self) -> *mut sys::AIBinder { 729 self.as_binder().as_native_mut() 730 } 731 } 732 733 /// Safety: `SpIBinder` guarantees that `binder` always contains a valid pointer 734 /// to an `AIBinder`, so we can trivially extract this pointer here. 735 unsafe impl AsNative<sys::AIBinder> for SpIBinder { as_native(&self) -> *const sys::AIBinder736 fn as_native(&self) -> *const sys::AIBinder { 737 self.0.as_ptr() 738 } 739 as_native_mut(&mut self) -> *mut sys::AIBinder740 fn as_native_mut(&mut self) -> *mut sys::AIBinder { 741 self.0.as_ptr() 742 } 743 } 744