blob: 4df557bee06c85666e38ab1a93bf7834fdb24395 [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::{
Alice Ryhl8618c482021-11-09 15:35:35 +000025 Parcel, BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
Stephen Crane2a3c2502020-06-16 17:48:35 -070026};
27use crate::sys;
28
Stephen Craneddb3e6d2020-12-18 13:27:22 -080029use std::cmp::Ordering;
Andrew Walbran12400d82021-03-04 17:04:34 +000030use std::convert::TryInto;
Stephen Crane098bbc92022-02-14 13:31:53 -080031use std::ffi::{c_void, CStr, CString};
Andrei Homescu2e3c1472020-08-11 16:35:40 -070032use std::fmt;
Alice Ryhlea9d9d22021-08-27 07:51:30 +000033use std::mem;
Stephen Crane098bbc92022-02-14 13:31:53 -080034use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070035use std::os::unix::io::AsRawFd;
36use std::ptr;
Alice Ryhlea9d9d22021-08-27 07:51:30 +000037use std::sync::Arc;
Stephen Crane2a3c2502020-06-16 17:48:35 -070038
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.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000043pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
Stephen Crane2a3c2502020-06-16 17:48:35 -070044
Andrei Homescu2e3c1472020-08-11 16:35:40 -070045impl fmt::Debug for SpIBinder {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.pad("SpIBinder")
48 }
49}
50
Stephen Crane2a3c2502020-06-16 17:48:35 -070051/// # Safety
52///
Stephen Cranef03fe3d2021-06-25 15:05:00 -070053/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
Stephen Crane2a3c2502020-06-16 17:48:35 -070054unsafe impl Send for SpIBinder {}
55
Stephen Cranef03fe3d2021-06-25 15:05:00 -070056/// # Safety
57///
58/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
59unsafe impl Sync for SpIBinder {}
60
Stephen Crane2a3c2502020-06-16 17:48:35 -070061impl SpIBinder {
62 /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
63 ///
64 /// # Safety
65 ///
66 /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
67 /// to an `AIBinder`.
68 ///
69 /// In the non-null case, this method conceptually takes ownership of a strong
70 /// reference to the object, so `AIBinder_incStrong` must have been called
71 /// on the pointer before passing it to this constructor. This is generally
72 /// done by Binder NDK methods that return an `AIBinder`, but care should be
73 /// taken to ensure this invariant.
74 ///
75 /// All `SpIBinder` objects that are constructed will hold a valid pointer
76 /// to an `AIBinder`, which will remain valid for the entire lifetime of the
77 /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
78 pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000079 ptr::NonNull::new(ptr).map(Self)
Stephen Crane2a3c2502020-06-16 17:48:35 -070080 }
81
Stephen Craned58bce02020-07-07 12:26:02 -070082 /// Extract a raw `AIBinder` pointer from this wrapper.
83 ///
84 /// This method should _only_ be used for testing. Do not try to use the NDK
85 /// interface directly for anything else.
86 ///
87 /// # Safety
88 ///
89 /// The resulting pointer is valid only as long as the SpIBinder is alive.
90 /// The SpIBinder object retains ownership of the AIBinder and the caller
91 /// should not attempt to free the returned pointer.
92 pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000093 self.0.as_ptr()
Stephen Craned58bce02020-07-07 12:26:02 -070094 }
95
Stephen Crane2a3c2502020-06-16 17:48:35 -070096 /// Return true if this binder object is hosted in a different process than
97 /// the current one.
98 pub fn is_remote(&self) -> bool {
99 unsafe {
100 // Safety: `SpIBinder` guarantees that it always contains a valid
101 // `AIBinder` pointer.
102 sys::AIBinder_isRemote(self.as_native())
103 }
104 }
105
106 /// Try to convert this Binder object into a trait object for the given
107 /// Binder interface.
108 ///
109 /// If this object does not implement the expected interface, the error
110 /// `StatusCode::BAD_TYPE` is returned.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800111 pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700112 FromIBinder::try_from(self)
113 }
114
115 /// Return the interface class of this binder object, if associated with
116 /// one.
Stephen Crane669deb62020-09-10 17:31:39 -0700117 pub fn get_class(&mut self) -> Option<InterfaceClass> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700118 unsafe {
119 // Safety: `SpIBinder` guarantees that it always contains a valid
120 // `AIBinder` pointer. `AIBinder_getClass` returns either a null
121 // pointer or a valid pointer to an `AIBinder_Class`. After mapping
122 // null to None, we can safely construct an `InterfaceClass` if the
123 // pointer was non-null.
124 let class = sys::AIBinder_getClass(self.as_native_mut());
125 class.as_ref().map(|p| InterfaceClass::from_ptr(p))
126 }
127 }
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000128
129 /// Creates a new weak reference to this binder object.
130 pub fn downgrade(&mut self) -> WpIBinder {
131 WpIBinder::new(self)
132 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700133}
134
Victor Hsiehd35d31d2021-06-03 11:24:31 -0700135pub mod unstable_api {
136 use super::{sys, SpIBinder};
137
138 /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
139 /// needed to bridge RPC binder, which doesn't have Rust API yet.
140 /// TODO(b/184872979): remove once the Rust API is created.
141 ///
142 /// # Safety
143 ///
144 /// See `SpIBinder::from_raw`.
145 pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
146 SpIBinder::from_raw(ptr)
147 }
148}
149
Stephen Crane2a3c2502020-06-16 17:48:35 -0700150/// An object that can be associate with an [`InterfaceClass`].
151pub trait AssociateClass {
152 /// Check if this object is a valid object for the given interface class
153 /// `I`.
154 ///
155 /// Returns `Some(self)` if this is a valid instance of the interface, and
156 /// `None` otherwise.
157 ///
158 /// Classes constructed by `InterfaceClass` are unique per type, so
159 /// repeatedly calling this method for the same `InterfaceClass` is allowed.
160 fn associate_class(&mut self, class: InterfaceClass) -> bool;
161}
162
163impl AssociateClass for SpIBinder {
164 fn associate_class(&mut self, class: InterfaceClass) -> bool {
165 unsafe {
166 // Safety: `SpIBinder` guarantees that it always contains a valid
167 // `AIBinder` pointer. An `InterfaceClass` can always be converted
168 // into a valid `AIBinder_Class` pointer, so these parameters are
169 // always safe.
170 sys::AIBinder_associateClass(self.as_native_mut(), class.into())
171 }
172 }
173}
174
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800175impl Ord for SpIBinder {
176 fn cmp(&self, other: &Self) -> Ordering {
177 let less_than = unsafe {
178 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
179 // this pointer is always safe to pass to `AIBinder_lt` (null is
180 // also safe to pass to this function, but we should never do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000181 sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800182 };
183 let greater_than = unsafe {
184 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
185 // this pointer is always safe to pass to `AIBinder_lt` (null is
186 // also safe to pass to this function, but we should never do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000187 sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800188 };
189 if !less_than && !greater_than {
190 Ordering::Equal
191 } else if less_than {
192 Ordering::Less
193 } else {
194 Ordering::Greater
195 }
196 }
197}
198
199impl PartialOrd for SpIBinder {
200 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
201 Some(self.cmp(other))
202 }
203}
204
Stephen Crane994a0f02020-08-11 14:47:29 -0700205impl PartialEq for SpIBinder {
206 fn eq(&self, other: &Self) -> bool {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000207 ptr::eq(self.0.as_ptr(), other.0.as_ptr())
Stephen Crane994a0f02020-08-11 14:47:29 -0700208 }
209}
210
211impl Eq for SpIBinder {}
212
Stephen Crane2a3c2502020-06-16 17:48:35 -0700213impl Clone for SpIBinder {
214 fn clone(&self) -> Self {
215 unsafe {
216 // Safety: Cloning a strong reference must increment the reference
217 // count. We are guaranteed by the `SpIBinder` constructor
218 // invariants that `self.0` is always a valid `AIBinder` pointer.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000219 sys::AIBinder_incStrong(self.0.as_ptr());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700220 }
221 Self(self.0)
222 }
223}
224
225impl Drop for SpIBinder {
226 // We hold a strong reference to the IBinder in SpIBinder and need to give up
227 // this reference on drop.
228 fn drop(&mut self) {
229 unsafe {
230 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
231 // know this pointer is safe to pass to `AIBinder_decStrong` here.
232 sys::AIBinder_decStrong(self.as_native_mut());
233 }
234 }
235}
236
Andrew Walbran12400d82021-03-04 17:04:34 +0000237impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
Alice Ryhl8618c482021-11-09 15:35:35 +0000238 fn prepare_transact(&self) -> Result<Parcel> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700239 let mut input = ptr::null_mut();
240 let status = unsafe {
241 // Safety: `SpIBinder` guarantees that `self` always contains a
242 // valid pointer to an `AIBinder`. It is safe to cast from an
243 // immutable pointer to a mutable pointer here, because
244 // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
245 // methods but the parameter is unfortunately not marked as const.
246 //
247 // After the call, input will be either a valid, owned `AParcel`
248 // pointer, or null.
249 sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
250 };
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000251
Stephen Crane2a3c2502020-06-16 17:48:35 -0700252 status_result(status)?;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000253
254 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700255 // Safety: At this point, `input` is either a valid, owned `AParcel`
Alice Ryhl268458c2021-09-15 12:56:10 +0000256 // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700257 // taking ownership of the parcel.
Alice Ryhl8618c482021-11-09 15:35:35 +0000258 Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000259 }
260 }
261
262 fn submit_transact(
263 &self,
264 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000265 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000266 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000267 ) -> Result<Parcel> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700268 let mut reply = ptr::null_mut();
269 let status = unsafe {
270 // Safety: `SpIBinder` guarantees that `self` always contains a
271 // valid pointer to an `AIBinder`. Although `IBinder::transact` is
272 // not a const method, it is still safe to cast our immutable
273 // pointer to mutable for the call. First, `IBinder::transact` is
274 // thread-safe, so concurrency is not an issue. The only way that
275 // `transact` can affect any visible, mutable state in the current
276 // process is by calling `onTransact` for a local service. However,
277 // in order for transactions to be thread-safe, this method must
278 // dynamically lock its data before modifying it. We enforce this
279 // property in Rust by requiring `Sync` for remotable objects and
280 // only providing `on_transact` with an immutable reference to
281 // `self`.
282 //
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000283 // This call takes ownership of the `data` parcel pointer, and
Stephen Crane2a3c2502020-06-16 17:48:35 -0700284 // passes ownership of the `reply` out parameter to its caller. It
285 // does not affect ownership of the `binder` parameter.
286 sys::AIBinder_transact(
287 self.as_native() as *mut sys::AIBinder,
288 code,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000289 &mut data.into_raw(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700290 &mut reply,
291 flags,
292 )
293 };
294 status_result(status)?;
295
296 unsafe {
297 // Safety: `reply` is either a valid `AParcel` pointer or null
298 // after the call to `AIBinder_transact` above, so we can
299 // construct a `Parcel` out of it. `AIBinder_transact` passes
300 // ownership of the `reply` parcel to Rust, so we need to
Alice Ryhl268458c2021-09-15 12:56:10 +0000301 // construct an owned variant.
Alice Ryhl8618c482021-11-09 15:35:35 +0000302 Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700303 }
304 }
305
306 fn is_binder_alive(&self) -> bool {
307 unsafe {
308 // Safety: `SpIBinder` guarantees that `self` always contains a
309 // valid pointer to an `AIBinder`.
310 //
311 // This call does not affect ownership of its pointer parameter.
312 sys::AIBinder_isAlive(self.as_native())
313 }
314 }
315
Janis Danisevskis1323d512021-11-09 07:48:08 -0800316 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700317 fn set_requesting_sid(&mut self, enable: bool) {
Andrew Walbran12400d82021-03-04 17:04:34 +0000318 unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700319 }
320
Stephen Crane2a3c2502020-06-16 17:48:35 -0700321 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
322 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
323 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
324 let status = unsafe {
325 // Safety: `SpIBinder` guarantees that `self` always contains a
326 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
327 // file descriptor parameter is always be a valid open file. The
328 // `args` pointer parameter is a valid pointer to an array of C
329 // strings that will outlive the call since `args` lives for the
330 // whole function scope.
331 //
332 // This call does not affect ownership of its binder pointer
333 // parameter and does not take ownership of the file or args array
334 // parameters.
335 sys::AIBinder_dump(
336 self.as_native_mut(),
337 fp.as_raw_fd(),
338 arg_ptrs.as_mut_ptr(),
339 arg_ptrs.len().try_into().unwrap(),
340 )
341 };
342 status_result(status)
343 }
344
345 fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
346 let mut out = ptr::null_mut();
347 let status = unsafe {
348 // Safety: `SpIBinder` guarantees that `self` always contains a
349 // valid pointer to an `AIBinder`. After this call, the `out`
350 // parameter will be either null, or a valid pointer to an
351 // `AIBinder`.
352 //
353 // This call passes ownership of the out pointer to its caller
354 // (assuming it is set to a non-null value).
355 sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
356 };
357 let ibinder = unsafe {
358 // Safety: The call above guarantees that `out` is either null or a
359 // valid, owned pointer to an `AIBinder`, both of which are safe to
360 // pass to `SpIBinder::from_raw`.
361 SpIBinder::from_raw(out)
362 };
363
364 status_result(status)?;
365 Ok(ibinder)
366 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000367}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700368
Andrew Walbran12400d82021-03-04 17:04:34 +0000369impl<T: AsNative<sys::AIBinder>> IBinder for T {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700370 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
371 status_result(unsafe {
372 // Safety: `SpIBinder` guarantees that `self` always contains a
373 // valid pointer to an `AIBinder`. `recipient` can always be
374 // converted into a valid pointer to an
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000375 // `AIBinder_DeathRecipient`.
376 //
377 // The cookie is also the correct pointer, and by calling new_cookie,
378 // we have created a new ref-count to the cookie, which linkToDeath
379 // takes ownership of. Once the DeathRecipient is unlinked for any
380 // reason (including if this call fails), the onUnlinked callback
381 // will consume that ref-count.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700382 sys::AIBinder_linkToDeath(
383 self.as_native_mut(),
384 recipient.as_native_mut(),
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000385 recipient.new_cookie(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700386 )
387 })
388 }
389
390 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
391 status_result(unsafe {
392 // Safety: `SpIBinder` guarantees that `self` always contains a
393 // valid pointer to an `AIBinder`. `recipient` can always be
394 // converted into a valid pointer to an
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800395 // `AIBinder_DeathRecipient`. Any value is safe to pass as the
Stephen Crane2a3c2502020-06-16 17:48:35 -0700396 // cookie, although we depend on this value being set by
397 // `get_cookie` when the death recipient callback is called.
398 sys::AIBinder_unlinkToDeath(
399 self.as_native_mut(),
400 recipient.as_native_mut(),
401 recipient.get_cookie(),
402 )
403 })
404 }
Stephen Crane61366d42022-01-20 17:45:34 -0800405
406 fn ping_binder(&mut self) -> Result<()> {
407 let status = unsafe {
408 // Safety: `SpIBinder` guarantees that `self` always contains a
409 // valid pointer to an `AIBinder`.
410 //
411 // This call does not affect ownership of its pointer parameter.
412 sys::AIBinder_ping(self.as_native_mut())
413 };
414 status_result(status)
415 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700416}
417
418impl Serialize for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000419 fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700420 parcel.write_binder(Some(self))
421 }
422}
423
424impl SerializeOption for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000425 fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700426 parcel.write_binder(this)
427 }
428}
429
430impl SerializeArray for SpIBinder {}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700431
432impl Deserialize for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000433 fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
Andrei Homescu32814372020-08-20 15:36:08 -0700434 parcel
435 .read_binder()
436 .transpose()
437 .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700438 }
439}
440
441impl DeserializeOption for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000442 fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700443 parcel.read_binder()
444 }
445}
446
447impl DeserializeArray for SpIBinder {}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700448
449/// A weak reference to a Binder remote object.
450///
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000451/// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
452/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000453pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700454
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000455impl fmt::Debug for WpIBinder {
456 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
457 f.pad("WpIBinder")
458 }
459}
460
461/// # Safety
462///
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700463/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000464unsafe impl Send for WpIBinder {}
465
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700466/// # Safety
467///
468/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
469unsafe impl Sync for WpIBinder {}
470
Stephen Crane2a3c2502020-06-16 17:48:35 -0700471impl WpIBinder {
472 /// Create a new weak reference from an object that can be converted into a
473 /// raw `AIBinder` pointer.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000474 fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700475 let ptr = unsafe {
476 // Safety: `SpIBinder` guarantees that `binder` always contains a
477 // valid pointer to an `AIBinder`.
478 sys::AIBinder_Weak_new(binder.as_native_mut())
479 };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000480 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700481 }
Stephen Crane994a0f02020-08-11 14:47:29 -0700482
483 /// Promote this weak reference to a strong reference to the binder object.
484 pub fn promote(&self) -> Option<SpIBinder> {
485 unsafe {
486 // Safety: `WpIBinder` always contains a valid weak reference, so we
487 // can pass this pointer to `AIBinder_Weak_promote`. Returns either
488 // null or an AIBinder owned by the caller, both of which are valid
489 // to pass to `SpIBinder::from_raw`.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000490 let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
Stephen Crane994a0f02020-08-11 14:47:29 -0700491 SpIBinder::from_raw(ptr)
492 }
493 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700494}
495
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800496impl Clone for WpIBinder {
497 fn clone(&self) -> Self {
498 let ptr = unsafe {
499 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
500 // so this pointer is always safe to pass to `AIBinder_Weak_clone`
501 // (although null is also a safe value to pass to this API).
502 //
503 // We get ownership of the returned pointer, so can construct a new
504 // WpIBinder object from it.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000505 sys::AIBinder_Weak_clone(self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800506 };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000507 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800508 }
509}
510
511impl Ord for WpIBinder {
512 fn cmp(&self, other: &Self) -> Ordering {
513 let less_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(self.0.as_ptr(), other.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800519 };
520 let greater_than = unsafe {
521 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
522 // so this pointer is always safe to pass to `AIBinder_Weak_lt`
523 // (null is also safe to pass to this function, but we should never
524 // do that).
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000525 sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800526 };
527 if !less_than && !greater_than {
528 Ordering::Equal
529 } else if less_than {
530 Ordering::Less
531 } else {
532 Ordering::Greater
533 }
534 }
535}
536
537impl PartialOrd for WpIBinder {
538 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
539 Some(self.cmp(other))
540 }
541}
542
543impl PartialEq for WpIBinder {
544 fn eq(&self, other: &Self) -> bool {
545 self.cmp(other) == Ordering::Equal
546 }
547}
548
549impl Eq for WpIBinder {}
550
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000551impl Drop for WpIBinder {
552 fn drop(&mut self) {
553 unsafe {
554 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
555 // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000556 sys::AIBinder_Weak_delete(self.0.as_ptr());
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000557 }
558 }
559}
560
Stephen Crane2a3c2502020-06-16 17:48:35 -0700561/// Rust wrapper around DeathRecipient objects.
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000562///
563/// The cookie in this struct represents an Arc<F> for the owned callback.
564/// This struct owns a ref-count of it, and so does every binder that we
565/// have been linked with.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700566#[repr(C)]
567pub struct DeathRecipient {
568 recipient: *mut sys::AIBinder_DeathRecipient,
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000569 cookie: *mut c_void,
570 vtable: &'static DeathRecipientVtable,
571}
572
573struct DeathRecipientVtable {
574 cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
575 cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700576}
577
Matthew Maurer51d76c82022-04-04 14:27:01 -0700578/// # Safety
579///
580/// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
581/// to a `Fn` which is `Sync` and `Send` (the cookie field). As
582/// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
583unsafe impl Send for DeathRecipient {}
584
585/// # Safety
586///
587/// A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and a pointer
588/// to a `Fn` which is `Sync` and `Send` (the cookie field). As
589/// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
590unsafe impl Sync for DeathRecipient {}
591
Stephen Crane2a3c2502020-06-16 17:48:35 -0700592impl DeathRecipient {
593 /// Create a new death recipient that will call the given callback when its
594 /// associated object dies.
595 pub fn new<F>(callback: F) -> DeathRecipient
596 where
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000597 F: Fn() + Send + Sync + 'static,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700598 {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000599 let callback: *const F = Arc::into_raw(Arc::new(callback));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700600 let recipient = unsafe {
601 // Safety: The function pointer is a valid death recipient callback.
602 //
603 // This call returns an owned `AIBinder_DeathRecipient` pointer
604 // which must be destroyed via `AIBinder_DeathRecipient_delete` when
605 // no longer needed.
606 sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
607 };
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000608 unsafe {
609 // Safety: The function pointer is a valid onUnlinked callback.
610 //
611 // All uses of linkToDeath in this file correctly increment the
612 // ref-count that this onUnlinked callback will decrement.
613 sys::AIBinder_DeathRecipient_setOnUnlinked(recipient, Some(Self::cookie_decr_refcount::<F>));
614 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700615 DeathRecipient {
616 recipient,
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000617 cookie: callback as *mut c_void,
618 vtable: &DeathRecipientVtable {
619 cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
620 cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
621 },
Stephen Crane2a3c2502020-06-16 17:48:35 -0700622 }
623 }
624
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000625 /// Increment the ref-count for the cookie and return it.
626 ///
627 /// # Safety
628 ///
629 /// The caller must handle the returned ref-count correctly.
630 unsafe fn new_cookie(&self) -> *mut c_void {
631 (self.vtable.cookie_incr_refcount)(self.cookie);
632
633 // Return a raw pointer with ownership of a ref-count
634 self.cookie
635 }
636
Stephen Crane2a3c2502020-06-16 17:48:35 -0700637 /// Get the opaque cookie that identifies this death recipient.
638 ///
639 /// This cookie will be used to link and unlink this death recipient to a
640 /// binder object and will be passed to the `binder_died` callback as an
641 /// opaque userdata pointer.
642 fn get_cookie(&self) -> *mut c_void {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000643 self.cookie
Stephen Crane2a3c2502020-06-16 17:48:35 -0700644 }
645
646 /// Callback invoked from C++ when the binder object dies.
647 ///
648 /// # Safety
649 ///
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000650 /// The `cookie` parameter must be the cookie for an Arc<F> and
651 /// the caller must hold a ref-count to it.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700652 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
653 where
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000654 F: Fn() + Send + Sync + 'static,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700655 {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000656 let callback = (cookie as *const F).as_ref().unwrap();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700657 callback();
658 }
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000659
660 /// Callback that decrements the ref-count.
661 /// This is invoked from C++ when a binder is unlinked.
662 ///
663 /// # Safety
664 ///
665 /// The `cookie` parameter must be the cookie for an Arc<F> and
666 /// the owner must give up a ref-count to it.
667 unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
668 where
669 F: Fn() + Send + Sync + 'static,
670 {
671 drop(Arc::from_raw(cookie as *const F));
672 }
673
674 /// Callback that increments the ref-count.
675 ///
676 /// # Safety
677 ///
678 /// The `cookie` parameter must be the cookie for an Arc<F> and
679 /// the owner must handle the created ref-count properly.
680 unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
681 where
682 F: Fn() + Send + Sync + 'static,
683 {
684 let arc = mem::ManuallyDrop::new(Arc::from_raw(cookie as *const F));
685 mem::forget(Arc::clone(&arc));
686 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700687}
688
689/// # Safety
690///
691/// A `DeathRecipient` is always constructed with a valid raw pointer to an
692/// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
693/// pointer.
694unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
695 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
696 self.recipient
697 }
698
699 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
700 self.recipient
701 }
702}
703
704impl Drop for DeathRecipient {
705 fn drop(&mut self) {
706 unsafe {
707 // Safety: `self.recipient` is always a valid, owned
708 // `AIBinder_DeathRecipient` pointer returned by
709 // `AIBinder_DeathRecipient_new` when `self` was created. This
710 // delete method can only be called once when `self` is dropped.
711 sys::AIBinder_DeathRecipient_delete(self.recipient);
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000712
713 // Safety: We own a ref-count to the cookie, and so does every
714 // linked binder. This call gives up our ref-count. The linked
715 // binders should already have given up their ref-count, or should
716 // do so shortly.
717 (self.vtable.cookie_decr_refcount)(self.cookie)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700718 }
719 }
720}
721
722/// Generic interface to remote binder objects.
723///
724/// Corresponds to the C++ `BpInterface` class.
725pub trait Proxy: Sized + Interface {
726 /// The Binder interface descriptor string.
727 ///
728 /// This string is a unique identifier for a Binder interface, and should be
729 /// the same between all implementations of that interface.
730 fn get_descriptor() -> &'static str;
731
732 /// Create a new interface from the given proxy, if it matches the expected
733 /// type of this interface.
734 fn from_binder(binder: SpIBinder) -> Result<Self>;
735}
736
737/// # Safety
738///
739/// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
740/// invocation of `IBinder` methods directly from `Interface` objects. It shares
741/// the same safety as the implementation for `SpIBinder`.
742unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
743 fn as_native(&self) -> *const sys::AIBinder {
744 self.as_binder().as_native()
745 }
746
747 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
748 self.as_binder().as_native_mut()
749 }
750}
751
752/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
753/// exist.
754pub fn get_service(name: &str) -> Option<SpIBinder> {
755 let name = CString::new(name).ok()?;
756 unsafe {
757 // Safety: `AServiceManager_getService` returns either a null pointer or
758 // a valid pointer to an owned `AIBinder`. Either of these values is
759 // safe to pass to `SpIBinder::from_raw`.
760 SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
761 }
762}
763
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000764/// Retrieve an existing service, or start it if it is configured as a dynamic
765/// service and isn't yet started.
766pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
767 let name = CString::new(name).ok()?;
768 unsafe {
769 // Safety: `AServiceManager_waitforService` returns either a null
770 // pointer or a valid pointer to an owned `AIBinder`. Either of these
771 // values is safe to pass to `SpIBinder::from_raw`.
772 SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
773 }
774}
775
Stephen Crane2a3c2502020-06-16 17:48:35 -0700776/// Retrieve an existing service for a particular interface, blocking for a few
777/// seconds if it doesn't yet exist.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800778pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700779 let service = get_service(name);
780 match service {
781 Some(service) => FromIBinder::try_from(service),
782 None => Err(StatusCode::NAME_NOT_FOUND),
783 }
784}
785
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000786/// Retrieve an existing service for a particular interface, or start it if it
787/// is configured as a dynamic service and isn't yet started.
788pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
789 let service = wait_for_service(name);
790 match service {
791 Some(service) => FromIBinder::try_from(service),
792 None => Err(StatusCode::NAME_NOT_FOUND),
793 }
794}
795
Stephen Crane098bbc92022-02-14 13:31:53 -0800796/// Check if a service is declared (e.g. in a VINTF manifest)
797pub fn is_declared(interface: &str) -> Result<bool> {
798 let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
799
800 unsafe {
801 // Safety: `interface` is a valid null-terminated C-style string and is
802 // only borrowed for the lifetime of the call. The `interface` local
803 // outlives this call as it lives for the function scope.
804 Ok(sys::AServiceManager_isDeclared(interface.as_ptr()))
805 }
806}
807
808/// Retrieve all declared instances for a particular interface
809///
810/// For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo'
811/// is passed here, then ["foo"] would be returned.
812pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
813 unsafe extern "C" fn callback(instance: *const c_char, opaque: *mut c_void) {
814 // Safety: opaque was a mutable pointer created below from a Vec of
815 // CString, and outlives this callback. The null handling here is just
816 // to avoid the possibility of unwinding across C code if this crate is
817 // ever compiled with panic=unwind.
818 if let Some(instances) = opaque.cast::<Vec<CString>>().as_mut() {
819 // Safety: instance is a valid null-terminated C string with a
820 // lifetime at least as long as this function, and we immediately
821 // copy it into an owned CString.
822 instances.push(CStr::from_ptr(instance).to_owned());
823 } else {
824 eprintln!("Opaque pointer was null in get_declared_instances callback!");
825 }
826 }
827
828 let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
829 let mut instances: Vec<CString> = vec![];
830 unsafe {
831 // Safety: `interface` and `instances` are borrowed for the length of
832 // this call and both outlive the call. `interface` is guaranteed to be
833 // a valid null-terminated C-style string.
834 sys::AServiceManager_forEachDeclaredInstance(
835 interface.as_ptr(),
836 &mut instances as *mut _ as *mut c_void,
837 Some(callback),
838 );
839 }
840
841 instances
842 .into_iter()
843 .map(CString::into_string)
844 .collect::<std::result::Result<Vec<String>, _>>()
845 .map_err(|e| {
846 eprintln!("An interface instance name was not a valid UTF-8 string: {}", e);
847 StatusCode::BAD_VALUE
848 })
849}
850
Stephen Crane2a3c2502020-06-16 17:48:35 -0700851/// # Safety
852///
853/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
854/// `AIBinder`, so we can trivially extract this pointer here.
855unsafe impl AsNative<sys::AIBinder> for SpIBinder {
856 fn as_native(&self) -> *const sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000857 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700858 }
859
860 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000861 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700862 }
863}