blob: e55f48b9893b492b4cb6700c8af69c2fa27c0924 [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::{
Matthew Maurere268a9f2022-07-26 09:31:30 -070025 BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize,
26 SerializeArray, SerializeOption,
Stephen Crane2a3c2502020-06-16 17:48:35 -070027};
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 Crane098bbc92022-02-14 13:31:53 -080032use std::ffi::{c_void, CStr, CString};
Andrei Homescu2e3c1472020-08-11 16:35:40 -070033use std::fmt;
Alice Ryhlea9d9d22021-08-27 07:51:30 +000034use std::mem;
Stephen Crane098bbc92022-02-14 13:31:53 -080035use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070036use std::os::unix::io::AsRawFd;
37use std::ptr;
Alice Ryhlea9d9d22021-08-27 07:51:30 +000038use std::sync::Arc;
Stephen Crane2a3c2502020-06-16 17:48:35 -070039
40/// A strong reference to a Binder remote object.
41///
42/// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
43/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000044pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
Stephen Crane2a3c2502020-06-16 17:48:35 -070045
Andrei Homescu2e3c1472020-08-11 16:35:40 -070046impl fmt::Debug for SpIBinder {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.pad("SpIBinder")
49 }
50}
51
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010052/// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is
53/// thread-safe.
Stephen Crane2a3c2502020-06-16 17:48:35 -070054unsafe impl Send for SpIBinder {}
55
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010056/// Safety: An `SpIBinder` is an immutable handle to a C++ IBinder, which is
57/// thread-safe.
Stephen Cranef03fe3d2021-06-25 15:05:00 -070058unsafe impl Sync for SpIBinder {}
59
Stephen Crane2a3c2502020-06-16 17:48:35 -070060impl SpIBinder {
61 /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
62 ///
63 /// # Safety
64 ///
65 /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
66 /// to an `AIBinder`.
67 ///
68 /// In the non-null case, this method conceptually takes ownership of a strong
69 /// reference to the object, so `AIBinder_incStrong` must have been called
70 /// on the pointer before passing it to this constructor. This is generally
71 /// done by Binder NDK methods that return an `AIBinder`, but care should be
72 /// taken to ensure this invariant.
73 ///
74 /// All `SpIBinder` objects that are constructed will hold a valid pointer
75 /// to an `AIBinder`, which will remain valid for the entire lifetime of the
76 /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
77 pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000078 ptr::NonNull::new(ptr).map(Self)
Stephen Crane2a3c2502020-06-16 17:48:35 -070079 }
80
Stephen Craned58bce02020-07-07 12:26:02 -070081 /// Extract a raw `AIBinder` pointer from this wrapper.
82 ///
83 /// This method should _only_ be used for testing. Do not try to use the NDK
84 /// interface directly for anything else.
85 ///
86 /// # Safety
87 ///
88 /// The resulting pointer is valid only as long as the SpIBinder is alive.
89 /// The SpIBinder object retains ownership of the AIBinder and the caller
90 /// should not attempt to free the returned pointer.
91 pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +000092 self.0.as_ptr()
Stephen Craned58bce02020-07-07 12:26:02 -070093 }
94
Stephen Crane2a3c2502020-06-16 17:48:35 -070095 /// Return true if this binder object is hosted in a different process than
96 /// the current one.
97 pub fn is_remote(&self) -> bool {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010098 // Safety: `SpIBinder` guarantees that it always contains a valid
99 // `AIBinder` pointer.
100 unsafe { sys::AIBinder_isRemote(self.as_native()) }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700101 }
102
103 /// Try to convert this Binder object into a trait object for the given
104 /// Binder interface.
105 ///
106 /// If this object does not implement the expected interface, the error
107 /// `StatusCode::BAD_TYPE` is returned.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800108 pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700109 FromIBinder::try_from(self)
110 }
111
112 /// Return the interface class of this binder object, if associated with
113 /// one.
Stephen Crane669deb62020-09-10 17:31:39 -0700114 pub fn get_class(&mut self) -> Option<InterfaceClass> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100115 // Safety: `SpIBinder` guarantees that it always contains a valid
116 // `AIBinder` pointer. `AIBinder_getClass` returns either a null
117 // pointer or a valid pointer to an `AIBinder_Class`. After mapping
118 // null to None, we can safely construct an `InterfaceClass` if the
119 // pointer was non-null.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700120 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700121 let class = sys::AIBinder_getClass(self.as_native_mut());
122 class.as_ref().map(|p| InterfaceClass::from_ptr(p))
123 }
124 }
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000125
126 /// Creates a new weak reference to this binder object.
127 pub fn downgrade(&mut self) -> WpIBinder {
128 WpIBinder::new(self)
129 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700130}
131
Andrew Walbranff136e02022-08-02 17:16:12 +0000132fn interface_cast<T: FromIBinder + ?Sized>(service: Option<SpIBinder>) -> Result<Strong<T>> {
133 if let Some(service) = service {
134 FromIBinder::try_from(service)
135 } else {
136 Err(StatusCode::NAME_NOT_FOUND)
137 }
138}
139
Victor Hsiehd35d31d2021-06-03 11:24:31 -0700140pub mod unstable_api {
141 use super::{sys, SpIBinder};
142
143 /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
144 /// needed to bridge RPC binder, which doesn't have Rust API yet.
145 /// TODO(b/184872979): remove once the Rust API is created.
146 ///
147 /// # Safety
148 ///
149 /// See `SpIBinder::from_raw`.
150 pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100151 // Safety: The caller makes the same guarantees as this requires.
152 unsafe { SpIBinder::from_raw(ptr) }
Victor Hsiehd35d31d2021-06-03 11:24:31 -0700153 }
154}
155
Stephen Crane2a3c2502020-06-16 17:48:35 -0700156/// An object that can be associate with an [`InterfaceClass`].
157pub trait AssociateClass {
158 /// Check if this object is a valid object for the given interface class
159 /// `I`.
160 ///
161 /// Returns `Some(self)` if this is a valid instance of the interface, and
162 /// `None` otherwise.
163 ///
164 /// Classes constructed by `InterfaceClass` are unique per type, so
165 /// repeatedly calling this method for the same `InterfaceClass` is allowed.
166 fn associate_class(&mut self, class: InterfaceClass) -> bool;
167}
168
169impl AssociateClass for SpIBinder {
170 fn associate_class(&mut self, class: InterfaceClass) -> bool {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100171 // Safety: `SpIBinder` guarantees that it always contains a valid
172 // `AIBinder` pointer. An `InterfaceClass` can always be converted
173 // into a valid `AIBinder_Class` pointer, so these parameters are
174 // always safe.
175 unsafe { sys::AIBinder_associateClass(self.as_native_mut(), class.into()) }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700176 }
177}
178
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800179impl Ord for SpIBinder {
180 fn cmp(&self, other: &Self) -> Ordering {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100181 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so this
182 // pointer is always safe to pass to `AIBinder_lt` (null is also safe to
183 // pass to this function, but we should never do that).
184 let less_than = unsafe { sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr()) };
185 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so this
186 // pointer is always safe to pass to `AIBinder_lt` (null is also safe to
187 // pass to this function, but we should never do that).
188 let greater_than = unsafe { sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr()) };
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800189 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 {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100215 // Safety: Cloning a strong reference must increment the reference
216 // count. We are guaranteed by the `SpIBinder` constructor
217 // invariants that `self.0` is always a valid `AIBinder` pointer.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700218 unsafe {
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) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100229 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
230 // know this pointer is safe to pass to `AIBinder_decStrong` here.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700231 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700232 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();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100240 // Safety: `SpIBinder` guarantees that `self` always contains a
241 // valid pointer to an `AIBinder`. It is safe to cast from an
242 // immutable pointer to a mutable pointer here, because
243 // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
244 // methods but the parameter is unfortunately not marked as const.
245 //
246 // After the call, input will be either a valid, owned `AParcel`
247 // pointer, or null.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700248 let status = unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700249 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
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100254 // Safety: At this point, `input` is either a valid, owned `AParcel`
255 // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
256 // taking ownership of the parcel.
257 unsafe { Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL) }
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000258 }
259
260 fn submit_transact(
261 &self,
262 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000263 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000264 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000265 ) -> Result<Parcel> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700266 let mut reply = ptr::null_mut();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100267 // Safety: `SpIBinder` guarantees that `self` always contains a
268 // valid pointer to an `AIBinder`. Although `IBinder::transact` is
269 // not a const method, it is still safe to cast our immutable
270 // pointer to mutable for the call. First, `IBinder::transact` is
271 // thread-safe, so concurrency is not an issue. The only way that
272 // `transact` can affect any visible, mutable state in the current
273 // process is by calling `onTransact` for a local service. However,
274 // in order for transactions to be thread-safe, this method must
275 // dynamically lock its data before modifying it. We enforce this
276 // property in Rust by requiring `Sync` for remotable objects and
277 // only providing `on_transact` with an immutable reference to
278 // `self`.
279 //
280 // This call takes ownership of the `data` parcel pointer, and
281 // passes ownership of the `reply` out parameter to its caller. It
282 // does not affect ownership of the `binder` parameter.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700283 let status = unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700284 sys::AIBinder_transact(
285 self.as_native() as *mut sys::AIBinder,
286 code,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000287 &mut data.into_raw(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700288 &mut reply,
289 flags,
290 )
291 };
292 status_result(status)?;
293
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100294 // Safety: `reply` is either a valid `AParcel` pointer or null
295 // after the call to `AIBinder_transact` above, so we can
296 // construct a `Parcel` out of it. `AIBinder_transact` passes
297 // ownership of the `reply` parcel to Rust, so we need to
298 // construct an owned variant.
299 unsafe { Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL) }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700300 }
301
302 fn is_binder_alive(&self) -> bool {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100303 // 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_isAlive(self.as_native()) }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700308 }
309
Janis Danisevskis1323d512021-11-09 07:48:08 -0800310 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700311 fn set_requesting_sid(&mut self, enable: bool) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100312 // Safety: `SpIBinder` guarantees that `self` always contains a valid
313 // pointer to an `AIBinder`.
314 //
315 // This call does not affect ownership of its pointer parameter.
Andrew Walbran12400d82021-03-04 17:04:34 +0000316 unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700317 }
318
Stephen Crane2a3c2502020-06-16 17:48:35 -0700319 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
320 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
321 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100322 // Safety: `SpIBinder` guarantees that `self` always contains a
323 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
324 // file descriptor parameter is always be a valid open file. The
325 // `args` pointer parameter is a valid pointer to an array of C
326 // strings that will outlive the call since `args` lives for the
327 // whole function scope.
328 //
329 // This call does not affect ownership of its binder pointer
330 // parameter and does not take ownership of the file or args array
331 // parameters.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700332 let status = unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700333 sys::AIBinder_dump(
334 self.as_native_mut(),
335 fp.as_raw_fd(),
336 arg_ptrs.as_mut_ptr(),
337 arg_ptrs.len().try_into().unwrap(),
338 )
339 };
340 status_result(status)
341 }
342
343 fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
344 let mut out = ptr::null_mut();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100345 // Safety: `SpIBinder` guarantees that `self` always contains a
346 // valid pointer to an `AIBinder`. After this call, the `out`
347 // parameter will be either null, or a valid pointer to an
348 // `AIBinder`.
349 //
350 // This call passes ownership of the out pointer to its caller
351 // (assuming it is set to a non-null value).
352 let status = unsafe { sys::AIBinder_getExtension(self.as_native_mut(), &mut out) };
353 // Safety: The call above guarantees that `out` is either null or a
354 // valid, owned pointer to an `AIBinder`, both of which are safe to
355 // pass to `SpIBinder::from_raw`.
356 let ibinder = unsafe { SpIBinder::from_raw(out) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700357
358 status_result(status)?;
359 Ok(ibinder)
360 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000361}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700362
Andrew Walbran12400d82021-03-04 17:04:34 +0000363impl<T: AsNative<sys::AIBinder>> IBinder for T {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700364 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100365 // Safety: `SpIBinder` guarantees that `self` always contains a
366 // valid pointer to an `AIBinder`. `recipient` can always be
367 // converted into a valid pointer to an
368 // `AIBinder_DeathRecipient`.
369 //
370 // The cookie is also the correct pointer, and by calling new_cookie,
371 // we have created a new ref-count to the cookie, which linkToDeath
372 // takes ownership of. Once the DeathRecipient is unlinked for any
373 // reason (including if this call fails), the onUnlinked callback
374 // will consume that ref-count.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700375 status_result(unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700376 sys::AIBinder_linkToDeath(
377 self.as_native_mut(),
378 recipient.as_native_mut(),
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000379 recipient.new_cookie(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700380 )
381 })
382 }
383
384 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100385 // Safety: `SpIBinder` guarantees that `self` always contains a
386 // valid pointer to an `AIBinder`. `recipient` can always be
387 // converted into a valid pointer to an
388 // `AIBinder_DeathRecipient`. Any value is safe to pass as the
389 // cookie, although we depend on this value being set by
390 // `get_cookie` when the death recipient callback is called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700391 status_result(unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700392 sys::AIBinder_unlinkToDeath(
393 self.as_native_mut(),
394 recipient.as_native_mut(),
395 recipient.get_cookie(),
396 )
397 })
398 }
Stephen Crane61366d42022-01-20 17:45:34 -0800399
400 fn ping_binder(&mut self) -> Result<()> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100401 // Safety: `SpIBinder` guarantees that `self` always contains a
402 // valid pointer to an `AIBinder`.
403 //
404 // This call does not affect ownership of its pointer parameter.
405 let status = unsafe { sys::AIBinder_ping(self.as_native_mut()) };
Stephen Crane61366d42022-01-20 17:45:34 -0800406 status_result(status)
407 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700408}
409
410impl Serialize for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000411 fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700412 parcel.write_binder(Some(self))
413 }
414}
415
416impl SerializeOption for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000417 fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700418 parcel.write_binder(this)
419 }
420}
421
422impl SerializeArray for SpIBinder {}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700423
424impl Deserialize for SpIBinder {
Andrei Homescu2b802f72023-05-05 03:21:43 +0000425 type UninitType = Option<Self>;
426 fn uninit() -> Self::UninitType {
427 Self::UninitType::default()
428 }
429 fn from_init(value: Self) -> Self::UninitType {
430 Some(value)
431 }
432
Alice Ryhl8618c482021-11-09 15:35:35 +0000433 fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700434 parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700435 }
436}
437
438impl DeserializeOption for SpIBinder {
Alice Ryhl8618c482021-11-09 15:35:35 +0000439 fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700440 parcel.read_binder()
441 }
442}
443
444impl DeserializeArray for SpIBinder {}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700445
446/// A weak reference to a Binder remote object.
447///
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000448/// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
449/// is untyped; typed interface access is implemented by the AIDL compiler.
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000450pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700451
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000452impl fmt::Debug for WpIBinder {
453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454 f.pad("WpIBinder")
455 }
456}
457
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100458/// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is
459/// thread-safe.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000460unsafe impl Send for WpIBinder {}
461
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100462/// Safety: A `WpIBinder` is an immutable handle to a C++ IBinder, which is
463/// thread-safe.
Stephen Cranef03fe3d2021-06-25 15:05:00 -0700464unsafe impl Sync for WpIBinder {}
465
Stephen Crane2a3c2502020-06-16 17:48:35 -0700466impl WpIBinder {
467 /// Create a new weak reference from an object that can be converted into a
468 /// raw `AIBinder` pointer.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000469 fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100470 // Safety: `SpIBinder` guarantees that `binder` always contains a valid
471 // pointer to an `AIBinder`.
472 let ptr = unsafe { sys::AIBinder_Weak_new(binder.as_native_mut()) };
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> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100478 // Safety: `WpIBinder` always contains a valid weak reference, so we can
479 // pass this pointer to `AIBinder_Weak_promote`. Returns either null or
480 // an AIBinder owned by the caller, both of which are valid to pass to
481 // `SpIBinder::from_raw`.
Stephen Crane994a0f02020-08-11 14:47:29 -0700482 unsafe {
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 {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100491 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so
492 // this pointer is always safe to pass to `AIBinder_Weak_clone`
493 // (although null is also a safe value to pass to this API).
494 //
495 // We get ownership of the returned pointer, so can construct a new
496 // WpIBinder object from it.
497 let ptr = unsafe { sys::AIBinder_Weak_clone(self.0.as_ptr()) };
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000498 Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800499 }
500}
501
502impl Ord for WpIBinder {
503 fn cmp(&self, other: &Self) -> Ordering {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100504 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so
505 // this pointer is always safe to pass to `AIBinder_Weak_lt` (null is
506 // also safe to pass to this function, but we should never do that).
507 let less_than = unsafe { sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr()) };
508 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so
509 // this pointer is always safe to pass to `AIBinder_Weak_lt` (null is
510 // also safe to pass to this function, but we should never do that).
511 let greater_than = unsafe { sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr()) };
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800512 if !less_than && !greater_than {
513 Ordering::Equal
514 } else if less_than {
515 Ordering::Less
516 } else {
517 Ordering::Greater
518 }
519 }
520}
521
522impl PartialOrd for WpIBinder {
523 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
524 Some(self.cmp(other))
525 }
526}
527
528impl PartialEq for WpIBinder {
529 fn eq(&self, other: &Self) -> bool {
530 self.cmp(other) == Ordering::Equal
531 }
532}
533
534impl Eq for WpIBinder {}
535
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000536impl Drop for WpIBinder {
537 fn drop(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100538 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
539 // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000540 unsafe {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000541 sys::AIBinder_Weak_delete(self.0.as_ptr());
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000542 }
543 }
544}
545
Stephen Crane2a3c2502020-06-16 17:48:35 -0700546/// Rust wrapper around DeathRecipient objects.
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000547///
548/// The cookie in this struct represents an Arc<F> for the owned callback.
549/// This struct owns a ref-count of it, and so does every binder that we
550/// have been linked with.
Matthew Maurera7eb0d42022-07-26 10:07:05 -0700551///
552/// Dropping the `DeathRecipient` will `unlink_to_death` any binders it is
553/// currently linked to.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700554#[repr(C)]
555pub struct DeathRecipient {
556 recipient: *mut sys::AIBinder_DeathRecipient,
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000557 cookie: *mut c_void,
558 vtable: &'static DeathRecipientVtable,
559}
560
561struct DeathRecipientVtable {
562 cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
563 cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700564}
565
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100566/// Safety: A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and
567/// a pointer to a `Fn` which is `Sync` and `Send` (the cookie field). As
Matthew Maurer51d76c82022-04-04 14:27:01 -0700568/// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
569unsafe impl Send for DeathRecipient {}
570
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100571/// Safety: A `DeathRecipient` is a wrapper around `AIBinder_DeathRecipient` and
572/// a pointer to a `Fn` which is `Sync` and `Send` (the cookie field). As
Matthew Maurer51d76c82022-04-04 14:27:01 -0700573/// `AIBinder_DeathRecipient` is threadsafe, this structure is too.
574unsafe impl Sync for DeathRecipient {}
575
Stephen Crane2a3c2502020-06-16 17:48:35 -0700576impl DeathRecipient {
577 /// Create a new death recipient that will call the given callback when its
578 /// associated object dies.
579 pub fn new<F>(callback: F) -> DeathRecipient
580 where
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000581 F: Fn() + Send + Sync + 'static,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700582 {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000583 let callback: *const F = Arc::into_raw(Arc::new(callback));
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100584 // Safety: The function pointer is a valid death recipient callback.
585 //
586 // This call returns an owned `AIBinder_DeathRecipient` pointer which
587 // must be destroyed via `AIBinder_DeathRecipient_delete` when no longer
588 // needed.
589 let recipient = unsafe { sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>)) };
590 // Safety: The function pointer is a valid onUnlinked callback.
591 //
592 // All uses of linkToDeath in this file correctly increment the
593 // ref-count that this onUnlinked callback will decrement.
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000594 unsafe {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700595 sys::AIBinder_DeathRecipient_setOnUnlinked(
596 recipient,
597 Some(Self::cookie_decr_refcount::<F>),
598 );
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000599 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700600 DeathRecipient {
601 recipient,
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000602 cookie: callback as *mut c_void,
603 vtable: &DeathRecipientVtable {
604 cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
605 cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
606 },
Stephen Crane2a3c2502020-06-16 17:48:35 -0700607 }
608 }
609
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000610 /// Increment the ref-count for the cookie and return it.
611 ///
612 /// # Safety
613 ///
614 /// The caller must handle the returned ref-count correctly.
615 unsafe fn new_cookie(&self) -> *mut c_void {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100616 // Safety: `cookie_incr_refcount` points to
617 // `Self::cookie_incr_refcount`, and `self.cookie` is the cookie for an
618 // Arc<F>.
619 unsafe {
620 (self.vtable.cookie_incr_refcount)(self.cookie);
621 }
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000622
623 // Return a raw pointer with ownership of a ref-count
624 self.cookie
625 }
626
Stephen Crane2a3c2502020-06-16 17:48:35 -0700627 /// Get the opaque cookie that identifies this death recipient.
628 ///
629 /// This cookie will be used to link and unlink this death recipient to a
630 /// binder object and will be passed to the `binder_died` callback as an
631 /// opaque userdata pointer.
632 fn get_cookie(&self) -> *mut c_void {
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000633 self.cookie
Stephen Crane2a3c2502020-06-16 17:48:35 -0700634 }
635
636 /// Callback invoked from C++ when the binder object dies.
637 ///
638 /// # Safety
639 ///
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000640 /// The `cookie` parameter must be the cookie for an Arc<F> and
641 /// the caller must hold a ref-count to it.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700642 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
643 where
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000644 F: Fn() + Send + Sync + 'static,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700645 {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100646 // Safety: The caller promises that `cookie` is for an Arc<F>.
647 let callback = unsafe { (cookie as *const F).as_ref().unwrap() };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700648 callback();
649 }
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000650
651 /// Callback that decrements the ref-count.
652 /// This is invoked from C++ when a binder is unlinked.
653 ///
654 /// # Safety
655 ///
656 /// The `cookie` parameter must be the cookie for an Arc<F> and
657 /// the owner must give up a ref-count to it.
658 unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
659 where
660 F: Fn() + Send + Sync + 'static,
661 {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100662 // Safety: The caller promises that `cookie` is for an Arc<F>.
663 drop(unsafe { Arc::from_raw(cookie as *const F) });
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000664 }
665
666 /// Callback that increments the ref-count.
667 ///
668 /// # Safety
669 ///
670 /// The `cookie` parameter must be the cookie for an Arc<F> and
671 /// the owner must handle the created ref-count properly.
672 unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
673 where
674 F: Fn() + Send + Sync + 'static,
675 {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100676 // Safety: The caller promises that `cookie` is for an Arc<F>.
677 let arc = mem::ManuallyDrop::new(unsafe { Arc::from_raw(cookie as *const F) });
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000678 mem::forget(Arc::clone(&arc));
679 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700680}
681
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100682/// Safety: A `DeathRecipient` is always constructed with a valid raw pointer to
683/// an `AIBinder_DeathRecipient`, so it is always type-safe to extract this
Stephen Crane2a3c2502020-06-16 17:48:35 -0700684/// pointer.
685unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
686 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
687 self.recipient
688 }
689
690 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
691 self.recipient
692 }
693}
694
695impl Drop for DeathRecipient {
696 fn drop(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100697 // Safety: `self.recipient` is always a valid, owned
698 // `AIBinder_DeathRecipient` pointer returned by
699 // `AIBinder_DeathRecipient_new` when `self` was created. This delete
700 // method can only be called once when `self` is dropped.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700701 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700702 sys::AIBinder_DeathRecipient_delete(self.recipient);
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100703 }
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000704
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100705 // Safety: We own a ref-count to the cookie, and so does every linked
706 // binder. This call gives up our ref-count. The linked binders should
707 // already have given up their ref-count, or should do so shortly.
708 unsafe {
709 (self.vtable.cookie_decr_refcount)(self.cookie);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700710 }
711 }
712}
713
714/// Generic interface to remote binder objects.
715///
716/// Corresponds to the C++ `BpInterface` class.
717pub trait Proxy: Sized + Interface {
718 /// The Binder interface descriptor string.
719 ///
720 /// This string is a unique identifier for a Binder interface, and should be
721 /// the same between all implementations of that interface.
722 fn get_descriptor() -> &'static str;
723
724 /// Create a new interface from the given proxy, if it matches the expected
725 /// type of this interface.
726 fn from_binder(binder: SpIBinder) -> Result<Self>;
727}
728
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100729/// Safety: This is a convenience method that wraps `AsNative` for `SpIBinder`
730/// to allow invocation of `IBinder` methods directly from `Interface` objects.
731/// It shares the same safety as the implementation for `SpIBinder`.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700732unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
733 fn as_native(&self) -> *const sys::AIBinder {
734 self.as_binder().as_native()
735 }
736
737 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
738 self.as_binder().as_native_mut()
739 }
740}
741
742/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
743/// exist.
744pub fn get_service(name: &str) -> Option<SpIBinder> {
745 let name = CString::new(name).ok()?;
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100746 // Safety: `AServiceManager_getService` returns either a null pointer or a
747 // valid pointer to an owned `AIBinder`. Either of these values is safe to
748 // pass to `SpIBinder::from_raw`.
749 unsafe { SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr())) }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700750}
751
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000752/// Retrieve an existing service, or start it if it is configured as a dynamic
753/// service and isn't yet started.
754pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
755 let name = CString::new(name).ok()?;
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100756 // Safety: `AServiceManager_waitforService` returns either a null pointer or
757 // a valid pointer to an owned `AIBinder`. Either of these values is safe to
758 // pass to `SpIBinder::from_raw`.
759 unsafe { SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr())) }
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000760}
761
Stephen Crane2a3c2502020-06-16 17:48:35 -0700762/// Retrieve an existing service for a particular interface, blocking for a few
763/// seconds if it doesn't yet exist.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800764pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
Andrew Walbranff136e02022-08-02 17:16:12 +0000765 interface_cast(get_service(name))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700766}
767
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000768/// Retrieve an existing service for a particular interface, or start it if it
769/// is configured as a dynamic service and isn't yet started.
770pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
Andrew Walbranff136e02022-08-02 17:16:12 +0000771 interface_cast(wait_for_service(name))
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000772}
773
Stephen Crane098bbc92022-02-14 13:31:53 -0800774/// Check if a service is declared (e.g. in a VINTF manifest)
775pub fn is_declared(interface: &str) -> Result<bool> {
776 let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
777
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100778 // Safety: `interface` is a valid null-terminated C-style string and is only
779 // borrowed for the lifetime of the call. The `interface` local outlives
780 // this call as it lives for the function scope.
781 unsafe { Ok(sys::AServiceManager_isDeclared(interface.as_ptr())) }
Stephen Crane098bbc92022-02-14 13:31:53 -0800782}
783
784/// Retrieve all declared instances for a particular interface
785///
786/// For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo'
787/// is passed here, then ["foo"] would be returned.
788pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
789 unsafe extern "C" fn callback(instance: *const c_char, opaque: *mut c_void) {
790 // Safety: opaque was a mutable pointer created below from a Vec of
791 // CString, and outlives this callback. The null handling here is just
792 // to avoid the possibility of unwinding across C code if this crate is
793 // ever compiled with panic=unwind.
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100794 if let Some(instances) = unsafe { opaque.cast::<Vec<CString>>().as_mut() } {
Stephen Crane098bbc92022-02-14 13:31:53 -0800795 // Safety: instance is a valid null-terminated C string with a
796 // lifetime at least as long as this function, and we immediately
797 // copy it into an owned CString.
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100798 unsafe {
799 instances.push(CStr::from_ptr(instance).to_owned());
800 }
Stephen Crane098bbc92022-02-14 13:31:53 -0800801 } else {
802 eprintln!("Opaque pointer was null in get_declared_instances callback!");
803 }
804 }
805
806 let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
807 let mut instances: Vec<CString> = vec![];
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100808 // Safety: `interface` and `instances` are borrowed for the length of this
809 // call and both outlive the call. `interface` is guaranteed to be a valid
810 // null-terminated C-style string.
Stephen Crane098bbc92022-02-14 13:31:53 -0800811 unsafe {
Stephen Crane098bbc92022-02-14 13:31:53 -0800812 sys::AServiceManager_forEachDeclaredInstance(
813 interface.as_ptr(),
814 &mut instances as *mut _ as *mut c_void,
815 Some(callback),
816 );
817 }
818
819 instances
820 .into_iter()
821 .map(CString::into_string)
822 .collect::<std::result::Result<Vec<String>, _>>()
823 .map_err(|e| {
824 eprintln!("An interface instance name was not a valid UTF-8 string: {}", e);
825 StatusCode::BAD_VALUE
826 })
827}
828
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100829/// Safety: `SpIBinder` guarantees that `binder` always contains a valid pointer
830/// to an `AIBinder`, so we can trivially extract this pointer here.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700831unsafe impl AsNative<sys::AIBinder> for SpIBinder {
832 fn as_native(&self) -> *const sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000833 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700834 }
835
836 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
Alice Ryhl8dde9bc2021-08-16 16:57:10 +0000837 self.0.as_ptr()
Stephen Crane2a3c2502020-06-16 17:48:35 -0700838 }
839}