blob: b03ed49e512e78ee8955b4bd816a56e060f3b6d8 [file] [log] [blame]
Stephen Crane2a3c2502020-06-16 17:48:35 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Rust API for interacting with a remote binder service.
18
19use crate::binder::{
Andrew Walbran12400d82021-03-04 17:04:34 +000020 AsNative, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Strong,
21 TransactionCode, TransactionFlags,
Stephen Crane2a3c2502020-06-16 17:48:35 -070022};
23use crate::error::{status_result, Result, StatusCode};
24use crate::parcel::{
25 Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
26 SerializeOption,
27};
28use crate::sys;
29
Stephen Craneddb3e6d2020-12-18 13:27:22 -080030use std::cmp::Ordering;
Andrew Walbran12400d82021-03-04 17:04:34 +000031use std::convert::TryInto;
Stephen Crane2a3c2502020-06-16 17:48:35 -070032use std::ffi::{c_void, CString};
Andrei Homescu2e3c1472020-08-11 16:35:40 -070033use std::fmt;
Stephen Crane2a3c2502020-06-16 17:48:35 -070034use std::os::unix::io::AsRawFd;
35use std::ptr;
36
37/// A strong reference to a Binder remote object.
38///
39/// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
40/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000041pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
Stephen Crane2a3c2502020-06-16 17:48:35 -070042
Andrei Homescu2e3c1472020-08-11 16:35:40 -070043impl fmt::Debug for SpIBinder {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 f.pad("SpIBinder")
46 }
47}
48
Stephen Crane2a3c2502020-06-16 17:48:35 -070049/// # Safety
50///
Stephen Cranef03fe3d2021-06-25 15:05:00 -070051/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
Stephen Crane2a3c2502020-06-16 17:48:35 -070052unsafe impl Send for SpIBinder {}
53
Stephen Cranef03fe3d2021-06-25 15:05:00 -070054/// # Safety
55///
56/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
57unsafe impl Sync for SpIBinder {}
58
Stephen Crane2a3c2502020-06-16 17:48:35 -070059impl 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).
76 pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000077 ptr::NonNull::new(ptr).map(Self)
Stephen Crane2a3c2502020-06-16 17:48:35 -070078 }
79
Stephen Craned58bce02020-07-07 12:26:02 -070080 /// 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.
90 pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000091 self.0.as_ptr()
Stephen Craned58bce02020-07-07 12:26:02 -070092 }
93
Stephen Crane2a3c2502020-06-16 17:48:35 -070094 /// Return true if this binder object is hosted in a different process than
95 /// the current one.
96 pub fn is_remote(&self) -> bool {
97 unsafe {
98 // Safety: `SpIBinder` guarantees that it always contains a valid
99 // `AIBinder` pointer.
100 sys::AIBinder_isRemote(self.as_native())
101 }
102 }
103
104 /// Try to convert this Binder object into a trait object for the given
105 /// Binder interface.
106 ///
107 /// If this object does not implement the expected interface, the error
108 /// `StatusCode::BAD_TYPE` is returned.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800109 pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700110 FromIBinder::try_from(self)
111 }
112
113 /// Return the interface class of this binder object, if associated with
114 /// one.
Stephen Crane669deb62020-09-10 17:31:39 -0700115 pub fn get_class(&mut self) -> Option<InterfaceClass> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700116 unsafe {
117 // Safety: `SpIBinder` guarantees that it always contains a valid
118 // `AIBinder` pointer. `AIBinder_getClass` returns either a null
119 // pointer or a valid pointer to an `AIBinder_Class`. After mapping
120 // null to None, we can safely construct an `InterfaceClass` if the
121 // pointer was non-null.
122 let class = sys::AIBinder_getClass(self.as_native_mut());
123 class.as_ref().map(|p| InterfaceClass::from_ptr(p))
124 }
125 }
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000126
127 /// Creates a new weak reference to this binder object.
128 pub fn downgrade(&mut self) -> WpIBinder {
129 WpIBinder::new(self)
130 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700131}
132
Victor Hsiehd35d31d2021-06-03 11:24:31 -0700133pub mod unstable_api {
134 use super::{sys, SpIBinder};
135
136 /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
137 /// needed to bridge RPC binder, which doesn't have Rust API yet.
138 /// TODO(b/184872979): remove once the Rust API is created.
139 ///
140 /// # Safety
141 ///
142 /// See `SpIBinder::from_raw`.
143 pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
144 SpIBinder::from_raw(ptr)
145 }
146}
147
Stephen Crane2a3c2502020-06-16 17:48:35 -0700148/// An object that can be associate with an [`InterfaceClass`].
149pub trait AssociateClass {
150 /// Check if this object is a valid object for the given interface class
151 /// `I`.
152 ///
153 /// Returns `Some(self)` if this is a valid instance of the interface, and
154 /// `None` otherwise.
155 ///
156 /// Classes constructed by `InterfaceClass` are unique per type, so
157 /// repeatedly calling this method for the same `InterfaceClass` is allowed.
158 fn associate_class(&mut self, class: InterfaceClass) -> bool;
159}
160
161impl AssociateClass for SpIBinder {
162 fn associate_class(&mut self, class: InterfaceClass) -> bool {
163 unsafe {
164 // Safety: `SpIBinder` guarantees that it always contains a valid
165 // `AIBinder` pointer. An `InterfaceClass` can always be converted
166 // into a valid `AIBinder_Class` pointer, so these parameters are
167 // always safe.
168 sys::AIBinder_associateClass(self.as_native_mut(), class.into())
169 }
170 }
171}
172
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800173impl Ord for SpIBinder {
174 fn cmp(&self, other: &Self) -> Ordering {
175 let less_than = unsafe {
176 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
177 // this pointer is always safe to pass to `AIBinder_lt` (null is
178 // also safe to pass to this function, but we should never do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000179 sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800180 };
181 let greater_than = unsafe {
182 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
183 // this pointer is always safe to pass to `AIBinder_lt` (null is
184 // also safe to pass to this function, but we should never do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000185 sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800186 };
187 if !less_than && !greater_than {
188 Ordering::Equal
189 } else if less_than {
190 Ordering::Less
191 } else {
192 Ordering::Greater
193 }
194 }
195}
196
197impl PartialOrd for SpIBinder {
198 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
199 Some(self.cmp(other))
200 }
201}
202
Stephen Crane994a0f02020-08-11 14:47:29 -0700203impl PartialEq for SpIBinder {
204 fn eq(&self, other: &Self) -> bool {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000205 ptr::eq(self.0.as_ptr(), other.0.as_ptr())
Stephen Crane994a0f02020-08-11 14:47:29 -0700206 }
207}
208
209impl Eq for SpIBinder {}
210
Stephen Crane2a3c2502020-06-16 17:48:35 -0700211impl Clone for SpIBinder {
212 fn clone(&self) -> Self {
213 unsafe {
214 // Safety: Cloning a strong reference must increment the reference
215 // count. We are guaranteed by the `SpIBinder` constructor
216 // invariants that `self.0` is always a valid `AIBinder` pointer.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000217 sys::AIBinder_incStrong(self.0.as_ptr());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700218 }
219 Self(self.0)
220 }
221}
222
223impl Drop for SpIBinder {
224 // We hold a strong reference to the IBinder in SpIBinder and need to give up
225 // this reference on drop.
226 fn drop(&mut self) {
227 unsafe {
228 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
229 // know this pointer is safe to pass to `AIBinder_decStrong` here.
230 sys::AIBinder_decStrong(self.as_native_mut());
231 }
232 }
233}
234
Andrew Walbran12400d82021-03-04 17:04:34 +0000235impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700236 /// Perform a binder transaction
237 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
238 &self,
239 code: TransactionCode,
240 flags: TransactionFlags,
241 input_callback: F,
242 ) -> Result<Parcel> {
243 let mut input = ptr::null_mut();
244 let status = unsafe {
245 // Safety: `SpIBinder` guarantees that `self` always contains a
246 // valid pointer to an `AIBinder`. It is safe to cast from an
247 // immutable pointer to a mutable pointer here, because
248 // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
249 // methods but the parameter is unfortunately not marked as const.
250 //
251 // After the call, input will be either a valid, owned `AParcel`
252 // pointer, or null.
253 sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
254 };
255 status_result(status)?;
256 let mut input = unsafe {
257 // Safety: At this point, `input` is either a valid, owned `AParcel`
258 // pointer, or null. `Parcel::owned` safely handles both cases,
259 // taking ownership of the parcel.
260 Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)?
261 };
262 input_callback(&mut input)?;
263 let mut reply = ptr::null_mut();
264 let status = unsafe {
265 // Safety: `SpIBinder` guarantees that `self` always contains a
266 // valid pointer to an `AIBinder`. Although `IBinder::transact` is
267 // not a const method, it is still safe to cast our immutable
268 // pointer to mutable for the call. First, `IBinder::transact` is
269 // thread-safe, so concurrency is not an issue. The only way that
270 // `transact` can affect any visible, mutable state in the current
271 // process is by calling `onTransact` for a local service. However,
272 // in order for transactions to be thread-safe, this method must
273 // dynamically lock its data before modifying it. We enforce this
274 // property in Rust by requiring `Sync` for remotable objects and
275 // only providing `on_transact` with an immutable reference to
276 // `self`.
277 //
278 // This call takes ownership of the `input` parcel pointer, and
279 // passes ownership of the `reply` out parameter to its caller. It
280 // does not affect ownership of the `binder` parameter.
281 sys::AIBinder_transact(
282 self.as_native() as *mut sys::AIBinder,
283 code,
284 &mut input.into_raw(),
285 &mut reply,
286 flags,
287 )
288 };
289 status_result(status)?;
290
291 unsafe {
292 // Safety: `reply` is either a valid `AParcel` pointer or null
293 // after the call to `AIBinder_transact` above, so we can
294 // construct a `Parcel` out of it. `AIBinder_transact` passes
295 // ownership of the `reply` parcel to Rust, so we need to
296 // construct an owned variant. `Parcel::owned` takes ownership
297 // of the parcel pointer.
298 Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL)
299 }
300 }
301
302 fn is_binder_alive(&self) -> bool {
303 unsafe {
304 // Safety: `SpIBinder` guarantees that `self` always contains a
305 // valid pointer to an `AIBinder`.
306 //
307 // This call does not affect ownership of its pointer parameter.
308 sys::AIBinder_isAlive(self.as_native())
309 }
310 }
311
312 fn ping_binder(&mut self) -> Result<()> {
313 let status = unsafe {
314 // Safety: `SpIBinder` guarantees that `self` always contains a
315 // valid pointer to an `AIBinder`.
316 //
317 // This call does not affect ownership of its pointer parameter.
318 sys::AIBinder_ping(self.as_native_mut())
319 };
320 status_result(status)
321 }
322
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700323 fn set_requesting_sid(&mut self, enable: bool) {
Andrew Walbran12400d82021-03-04 17:04:34 +0000324 unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700325 }
326
Stephen Crane2a3c2502020-06-16 17:48:35 -0700327 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
328 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
329 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
330 let status = unsafe {
331 // Safety: `SpIBinder` guarantees that `self` always contains a
332 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
333 // file descriptor parameter is always be a valid open file. The
334 // `args` pointer parameter is a valid pointer to an array of C
335 // strings that will outlive the call since `args` lives for the
336 // whole function scope.
337 //
338 // This call does not affect ownership of its binder pointer
339 // parameter and does not take ownership of the file or args array
340 // parameters.
341 sys::AIBinder_dump(
342 self.as_native_mut(),
343 fp.as_raw_fd(),
344 arg_ptrs.as_mut_ptr(),
345 arg_ptrs.len().try_into().unwrap(),
346 )
347 };
348 status_result(status)
349 }
350
351 fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
352 let mut out = ptr::null_mut();
353 let status = unsafe {
354 // Safety: `SpIBinder` guarantees that `self` always contains a
355 // valid pointer to an `AIBinder`. After this call, the `out`
356 // parameter will be either null, or a valid pointer to an
357 // `AIBinder`.
358 //
359 // This call passes ownership of the out pointer to its caller
360 // (assuming it is set to a non-null value).
361 sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
362 };
363 let ibinder = unsafe {
364 // Safety: The call above guarantees that `out` is either null or a
365 // valid, owned pointer to an `AIBinder`, both of which are safe to
366 // pass to `SpIBinder::from_raw`.
367 SpIBinder::from_raw(out)
368 };
369
370 status_result(status)?;
371 Ok(ibinder)
372 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000373}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700374
Andrew Walbran12400d82021-03-04 17:04:34 +0000375impl<T: AsNative<sys::AIBinder>> IBinder for T {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700376 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
377 status_result(unsafe {
378 // Safety: `SpIBinder` guarantees that `self` always contains a
379 // valid pointer to an `AIBinder`. `recipient` can always be
380 // converted into a valid pointer to an
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800381 // `AIBinder_DeathRecipient`. Any value is safe to pass as the
Stephen Crane2a3c2502020-06-16 17:48:35 -0700382 // cookie, although we depend on this value being set by
383 // `get_cookie` when the death recipient callback is called.
384 sys::AIBinder_linkToDeath(
385 self.as_native_mut(),
386 recipient.as_native_mut(),
387 recipient.get_cookie(),
388 )
389 })
390 }
391
392 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
393 status_result(unsafe {
394 // Safety: `SpIBinder` guarantees that `self` always contains a
395 // valid pointer to an `AIBinder`. `recipient` can always be
396 // converted into a valid pointer to an
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800397 // `AIBinder_DeathRecipient`. Any value is safe to pass as the
Stephen Crane2a3c2502020-06-16 17:48:35 -0700398 // cookie, although we depend on this value being set by
399 // `get_cookie` when the death recipient callback is called.
400 sys::AIBinder_unlinkToDeath(
401 self.as_native_mut(),
402 recipient.as_native_mut(),
403 recipient.get_cookie(),
404 )
405 })
406 }
407}
408
409impl Serialize for SpIBinder {
410 fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
411 parcel.write_binder(Some(self))
412 }
413}
414
415impl SerializeOption for SpIBinder {
416 fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
417 parcel.write_binder(this)
418 }
419}
420
421impl SerializeArray for SpIBinder {}
422impl SerializeArray for Option<&SpIBinder> {}
423
424impl Deserialize for SpIBinder {
425 fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
Andrei Homescu32814372020-08-20 15:36:08 -0700426 parcel
427 .read_binder()
428 .transpose()
429 .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700430 }
431}
432
433impl DeserializeOption for SpIBinder {
434 fn deserialize_option(parcel: &Parcel) -> Result<Option<SpIBinder>> {
435 parcel.read_binder()
436 }
437}
438
439impl DeserializeArray for SpIBinder {}
440impl DeserializeArray for Option<SpIBinder> {}
441
442/// A weak reference to a Binder remote object.
443///
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000444/// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
445/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000446pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700447
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000448impl fmt::Debug for WpIBinder {
449 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450 f.pad("WpIBinder")
451 }
452}
453
454/// # Safety
455///
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700456/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000457unsafe impl Send for WpIBinder {}
458
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700459/// # Safety
460///
461/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
462unsafe impl Sync for WpIBinder {}
463
Stephen Crane2a3c2502020-06-16 17:48:35 -0700464impl WpIBinder {
465 /// Create a new weak reference from an object that can be converted into a
466 /// raw `AIBinder` pointer.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000467 fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700468 let ptr = unsafe {
469 // Safety: `SpIBinder` guarantees that `binder` always contains a
470 // valid pointer to an `AIBinder`.
471 sys::AIBinder_Weak_new(binder.as_native_mut())
472 };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000473 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700474 }
Stephen Crane994a0f02020-08-11 14:47:29 -0700475
476 /// Promote this weak reference to a strong reference to the binder object.
477 pub fn promote(&self) -> Option<SpIBinder> {
478 unsafe {
479 // Safety: `WpIBinder` always contains a valid weak reference, so we
480 // can pass this pointer to `AIBinder_Weak_promote`. Returns either
481 // null or an AIBinder owned by the caller, both of which are valid
482 // to pass to `SpIBinder::from_raw`.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000483 let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
Stephen Crane994a0f02020-08-11 14:47:29 -0700484 SpIBinder::from_raw(ptr)
485 }
486 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700487}
488
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800489impl Clone for WpIBinder {
490 fn clone(&self) -> Self {
491 let ptr = unsafe {
492 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
493 // so this pointer is always safe to pass to `AIBinder_Weak_clone`
494 // (although null is also a safe value to pass to this API).
495 //
496 // We get ownership of the returned pointer, so can construct a new
497 // WpIBinder object from it.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000498 sys::AIBinder_Weak_clone(self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800499 };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000500 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800501 }
502}
503
504impl Ord for WpIBinder {
505 fn cmp(&self, other: &Self) -> Ordering {
506 let less_than = unsafe {
507 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
508 // so this pointer is always safe to pass to `AIBinder_Weak_lt`
509 // (null is also safe to pass to this function, but we should never
510 // do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000511 sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800512 };
513 let greater_than = unsafe {
514 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
515 // so this pointer is always safe to pass to `AIBinder_Weak_lt`
516 // (null is also safe to pass to this function, but we should never
517 // do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000518 sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800519 };
520 if !less_than && !greater_than {
521 Ordering::Equal
522 } else if less_than {
523 Ordering::Less
524 } else {
525 Ordering::Greater
526 }
527 }
528}
529
530impl PartialOrd for WpIBinder {
531 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
532 Some(self.cmp(other))
533 }
534}
535
536impl PartialEq for WpIBinder {
537 fn eq(&self, other: &Self) -> bool {
538 self.cmp(other) == Ordering::Equal
539 }
540}
541
542impl Eq for WpIBinder {}
543
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000544impl Drop for WpIBinder {
545 fn drop(&mut self) {
546 unsafe {
547 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
548 // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000549 sys::AIBinder_Weak_delete(self.0.as_ptr());
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000550 }
551 }
552}
553
Stephen Crane2a3c2502020-06-16 17:48:35 -0700554/// Rust wrapper around DeathRecipient objects.
555#[repr(C)]
556pub struct DeathRecipient {
557 recipient: *mut sys::AIBinder_DeathRecipient,
558 callback: Box<dyn Fn() + Send + 'static>,
559}
560
561impl DeathRecipient {
562 /// Create a new death recipient that will call the given callback when its
563 /// associated object dies.
564 pub fn new<F>(callback: F) -> DeathRecipient
565 where
566 F: Fn() + Send + 'static,
567 {
568 let callback = Box::new(callback);
569 let recipient = unsafe {
570 // Safety: The function pointer is a valid death recipient callback.
571 //
572 // This call returns an owned `AIBinder_DeathRecipient` pointer
573 // which must be destroyed via `AIBinder_DeathRecipient_delete` when
574 // no longer needed.
575 sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
576 };
577 DeathRecipient {
578 recipient,
579 callback,
580 }
581 }
582
583 /// Get the opaque cookie that identifies this death recipient.
584 ///
585 /// This cookie will be used to link and unlink this death recipient to a
586 /// binder object and will be passed to the `binder_died` callback as an
587 /// opaque userdata pointer.
588 fn get_cookie(&self) -> *mut c_void {
589 &*self.callback as *const _ as *mut c_void
590 }
591
592 /// Callback invoked from C++ when the binder object dies.
593 ///
594 /// # Safety
595 ///
596 /// The `cookie` parameter must have been created with the `get_cookie`
597 /// method of this object.
598 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
599 where
600 F: Fn() + Send + 'static,
601 {
602 let callback = (cookie as *mut F).as_ref().unwrap();
603 callback();
604 }
605}
606
607/// # Safety
608///
609/// A `DeathRecipient` is always constructed with a valid raw pointer to an
610/// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
611/// pointer.
612unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
613 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
614 self.recipient
615 }
616
617 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
618 self.recipient
619 }
620}
621
622impl Drop for DeathRecipient {
623 fn drop(&mut self) {
624 unsafe {
625 // Safety: `self.recipient` is always a valid, owned
626 // `AIBinder_DeathRecipient` pointer returned by
627 // `AIBinder_DeathRecipient_new` when `self` was created. This
628 // delete method can only be called once when `self` is dropped.
629 sys::AIBinder_DeathRecipient_delete(self.recipient);
630 }
631 }
632}
633
634/// Generic interface to remote binder objects.
635///
636/// Corresponds to the C++ `BpInterface` class.
637pub trait Proxy: Sized + Interface {
638 /// The Binder interface descriptor string.
639 ///
640 /// This string is a unique identifier for a Binder interface, and should be
641 /// the same between all implementations of that interface.
642 fn get_descriptor() -> &'static str;
643
644 /// Create a new interface from the given proxy, if it matches the expected
645 /// type of this interface.
646 fn from_binder(binder: SpIBinder) -> Result<Self>;
647}
648
649/// # Safety
650///
651/// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
652/// invocation of `IBinder` methods directly from `Interface` objects. It shares
653/// the same safety as the implementation for `SpIBinder`.
654unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
655 fn as_native(&self) -> *const sys::AIBinder {
656 self.as_binder().as_native()
657 }
658
659 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
660 self.as_binder().as_native_mut()
661 }
662}
663
664/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
665/// exist.
666pub fn get_service(name: &str) -> Option<SpIBinder> {
667 let name = CString::new(name).ok()?;
668 unsafe {
669 // Safety: `AServiceManager_getService` returns either a null pointer or
670 // a valid pointer to an owned `AIBinder`. Either of these values is
671 // safe to pass to `SpIBinder::from_raw`.
672 SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
673 }
674}
675
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000676/// Retrieve an existing service, or start it if it is configured as a dynamic
677/// service and isn't yet started.
678pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
679 let name = CString::new(name).ok()?;
680 unsafe {
681 // Safety: `AServiceManager_waitforService` returns either a null
682 // pointer or a valid pointer to an owned `AIBinder`. Either of these
683 // values is safe to pass to `SpIBinder::from_raw`.
684 SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
685 }
686}
687
Stephen Crane2a3c2502020-06-16 17:48:35 -0700688/// Retrieve an existing service for a particular interface, blocking for a few
689/// seconds if it doesn't yet exist.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800690pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700691 let service = get_service(name);
692 match service {
693 Some(service) => FromIBinder::try_from(service),
694 None => Err(StatusCode::NAME_NOT_FOUND),
695 }
696}
697
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000698/// Retrieve an existing service for a particular interface, or start it if it
699/// is configured as a dynamic service and isn't yet started.
700pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
701 let service = wait_for_service(name);
702 match service {
703 Some(service) => FromIBinder::try_from(service),
704 None => Err(StatusCode::NAME_NOT_FOUND),
705 }
706}
707
Stephen Crane2a3c2502020-06-16 17:48:35 -0700708/// # Safety
709///
710/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
711/// `AIBinder`, so we can trivially extract this pointer here.
712unsafe impl AsNative<sys::AIBinder> for SpIBinder {
713 fn as_native(&self) -> *const sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000714 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700715 }
716
717 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000718 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700719 }
720}