blob: e9e74c05e841a526dd133c5391048261121c464b [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::{
20 AsNative, FromIBinder, IBinder, Interface, InterfaceClass, TransactionCode, TransactionFlags,
21};
22use crate::error::{status_result, Result, StatusCode};
23use crate::parcel::{
24 Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
25 SerializeOption,
26};
27use crate::sys;
28
29use std::convert::TryInto;
30use std::ffi::{c_void, CString};
Andrei Homescu2e3c1472020-08-11 16:35:40 -070031use std::fmt;
Stephen Crane2a3c2502020-06-16 17:48:35 -070032use std::os::unix::io::AsRawFd;
33use std::ptr;
34
35/// A strong reference to a Binder remote object.
36///
37/// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
38/// is untyped; typed interface access is implemented by the AIDL compiler.
39pub struct SpIBinder(*mut sys::AIBinder);
40
Andrei Homescu2e3c1472020-08-11 16:35:40 -070041impl fmt::Debug for SpIBinder {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 f.pad("SpIBinder")
44 }
45}
46
Stephen Crane2a3c2502020-06-16 17:48:35 -070047/// # Safety
48///
49/// An `SpIBinder` is a handle to a C++ IBinder, which is thread-safe
50unsafe impl Send for SpIBinder {}
51
52impl SpIBinder {
53 /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
54 ///
55 /// # Safety
56 ///
57 /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
58 /// to an `AIBinder`.
59 ///
60 /// In the non-null case, this method conceptually takes ownership of a strong
61 /// reference to the object, so `AIBinder_incStrong` must have been called
62 /// on the pointer before passing it to this constructor. This is generally
63 /// done by Binder NDK methods that return an `AIBinder`, but care should be
64 /// taken to ensure this invariant.
65 ///
66 /// All `SpIBinder` objects that are constructed will hold a valid pointer
67 /// to an `AIBinder`, which will remain valid for the entire lifetime of the
68 /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
69 pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
70 ptr.as_mut().map(|p| Self(p))
71 }
72
Stephen Craned58bce02020-07-07 12:26:02 -070073 /// Extract a raw `AIBinder` pointer from this wrapper.
74 ///
75 /// This method should _only_ be used for testing. Do not try to use the NDK
76 /// interface directly for anything else.
77 ///
78 /// # Safety
79 ///
80 /// The resulting pointer is valid only as long as the SpIBinder is alive.
81 /// The SpIBinder object retains ownership of the AIBinder and the caller
82 /// should not attempt to free the returned pointer.
83 pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
84 self.0
85 }
86
Stephen Crane2a3c2502020-06-16 17:48:35 -070087 /// Return true if this binder object is hosted in a different process than
88 /// the current one.
89 pub fn is_remote(&self) -> bool {
90 unsafe {
91 // Safety: `SpIBinder` guarantees that it always contains a valid
92 // `AIBinder` pointer.
93 sys::AIBinder_isRemote(self.as_native())
94 }
95 }
96
97 /// Try to convert this Binder object into a trait object for the given
98 /// Binder interface.
99 ///
100 /// If this object does not implement the expected interface, the error
101 /// `StatusCode::BAD_TYPE` is returned.
102 pub fn into_interface<I: FromIBinder + ?Sized>(self) -> Result<Box<I>> {
103 FromIBinder::try_from(self)
104 }
105
106 /// Return the interface class of this binder object, if associated with
107 /// one.
Stephen Crane669deb62020-09-10 17:31:39 -0700108 pub fn get_class(&mut self) -> Option<InterfaceClass> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700109 unsafe {
110 // Safety: `SpIBinder` guarantees that it always contains a valid
111 // `AIBinder` pointer. `AIBinder_getClass` returns either a null
112 // pointer or a valid pointer to an `AIBinder_Class`. After mapping
113 // null to None, we can safely construct an `InterfaceClass` if the
114 // pointer was non-null.
115 let class = sys::AIBinder_getClass(self.as_native_mut());
116 class.as_ref().map(|p| InterfaceClass::from_ptr(p))
117 }
118 }
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000119
120 /// Creates a new weak reference to this binder object.
121 pub fn downgrade(&mut self) -> WpIBinder {
122 WpIBinder::new(self)
123 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700124}
125
126/// An object that can be associate with an [`InterfaceClass`].
127pub trait AssociateClass {
128 /// Check if this object is a valid object for the given interface class
129 /// `I`.
130 ///
131 /// Returns `Some(self)` if this is a valid instance of the interface, and
132 /// `None` otherwise.
133 ///
134 /// Classes constructed by `InterfaceClass` are unique per type, so
135 /// repeatedly calling this method for the same `InterfaceClass` is allowed.
136 fn associate_class(&mut self, class: InterfaceClass) -> bool;
137}
138
139impl AssociateClass for SpIBinder {
140 fn associate_class(&mut self, class: InterfaceClass) -> bool {
141 unsafe {
142 // Safety: `SpIBinder` guarantees that it always contains a valid
143 // `AIBinder` pointer. An `InterfaceClass` can always be converted
144 // into a valid `AIBinder_Class` pointer, so these parameters are
145 // always safe.
146 sys::AIBinder_associateClass(self.as_native_mut(), class.into())
147 }
148 }
149}
150
Stephen Crane994a0f02020-08-11 14:47:29 -0700151impl PartialEq for SpIBinder {
152 fn eq(&self, other: &Self) -> bool {
153 ptr::eq(self.0, other.0)
154 }
155}
156
157impl Eq for SpIBinder {}
158
Stephen Crane2a3c2502020-06-16 17:48:35 -0700159impl Clone for SpIBinder {
160 fn clone(&self) -> Self {
161 unsafe {
162 // Safety: Cloning a strong reference must increment the reference
163 // count. We are guaranteed by the `SpIBinder` constructor
164 // invariants that `self.0` is always a valid `AIBinder` pointer.
165 sys::AIBinder_incStrong(self.0);
166 }
167 Self(self.0)
168 }
169}
170
171impl Drop for SpIBinder {
172 // We hold a strong reference to the IBinder in SpIBinder and need to give up
173 // this reference on drop.
174 fn drop(&mut self) {
175 unsafe {
176 // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
177 // know this pointer is safe to pass to `AIBinder_decStrong` here.
178 sys::AIBinder_decStrong(self.as_native_mut());
179 }
180 }
181}
182
183impl<T: AsNative<sys::AIBinder>> IBinder for T {
184 /// Perform a binder transaction
185 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
186 &self,
187 code: TransactionCode,
188 flags: TransactionFlags,
189 input_callback: F,
190 ) -> Result<Parcel> {
191 let mut input = ptr::null_mut();
192 let status = unsafe {
193 // Safety: `SpIBinder` guarantees that `self` always contains a
194 // valid pointer to an `AIBinder`. It is safe to cast from an
195 // immutable pointer to a mutable pointer here, because
196 // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
197 // methods but the parameter is unfortunately not marked as const.
198 //
199 // After the call, input will be either a valid, owned `AParcel`
200 // pointer, or null.
201 sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
202 };
203 status_result(status)?;
204 let mut input = unsafe {
205 // Safety: At this point, `input` is either a valid, owned `AParcel`
206 // pointer, or null. `Parcel::owned` safely handles both cases,
207 // taking ownership of the parcel.
208 Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)?
209 };
210 input_callback(&mut input)?;
211 let mut reply = ptr::null_mut();
212 let status = unsafe {
213 // Safety: `SpIBinder` guarantees that `self` always contains a
214 // valid pointer to an `AIBinder`. Although `IBinder::transact` is
215 // not a const method, it is still safe to cast our immutable
216 // pointer to mutable for the call. First, `IBinder::transact` is
217 // thread-safe, so concurrency is not an issue. The only way that
218 // `transact` can affect any visible, mutable state in the current
219 // process is by calling `onTransact` for a local service. However,
220 // in order for transactions to be thread-safe, this method must
221 // dynamically lock its data before modifying it. We enforce this
222 // property in Rust by requiring `Sync` for remotable objects and
223 // only providing `on_transact` with an immutable reference to
224 // `self`.
225 //
226 // This call takes ownership of the `input` parcel pointer, and
227 // passes ownership of the `reply` out parameter to its caller. It
228 // does not affect ownership of the `binder` parameter.
229 sys::AIBinder_transact(
230 self.as_native() as *mut sys::AIBinder,
231 code,
232 &mut input.into_raw(),
233 &mut reply,
234 flags,
235 )
236 };
237 status_result(status)?;
238
239 unsafe {
240 // Safety: `reply` is either a valid `AParcel` pointer or null
241 // after the call to `AIBinder_transact` above, so we can
242 // construct a `Parcel` out of it. `AIBinder_transact` passes
243 // ownership of the `reply` parcel to Rust, so we need to
244 // construct an owned variant. `Parcel::owned` takes ownership
245 // of the parcel pointer.
246 Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL)
247 }
248 }
249
250 fn is_binder_alive(&self) -> bool {
251 unsafe {
252 // Safety: `SpIBinder` guarantees that `self` always contains a
253 // valid pointer to an `AIBinder`.
254 //
255 // This call does not affect ownership of its pointer parameter.
256 sys::AIBinder_isAlive(self.as_native())
257 }
258 }
259
260 fn ping_binder(&mut self) -> Result<()> {
261 let status = unsafe {
262 // Safety: `SpIBinder` guarantees that `self` always contains a
263 // valid pointer to an `AIBinder`.
264 //
265 // This call does not affect ownership of its pointer parameter.
266 sys::AIBinder_ping(self.as_native_mut())
267 };
268 status_result(status)
269 }
270
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700271 fn set_requesting_sid(&mut self, enable: bool) {
272 unsafe {
273 sys::AIBinder_setRequestingSid(self.as_native_mut(), enable)
274 };
275 }
276
Stephen Crane2a3c2502020-06-16 17:48:35 -0700277 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
278 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
279 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
280 let status = unsafe {
281 // Safety: `SpIBinder` guarantees that `self` always contains a
282 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
283 // file descriptor parameter is always be a valid open file. The
284 // `args` pointer parameter is a valid pointer to an array of C
285 // strings that will outlive the call since `args` lives for the
286 // whole function scope.
287 //
288 // This call does not affect ownership of its binder pointer
289 // parameter and does not take ownership of the file or args array
290 // parameters.
291 sys::AIBinder_dump(
292 self.as_native_mut(),
293 fp.as_raw_fd(),
294 arg_ptrs.as_mut_ptr(),
295 arg_ptrs.len().try_into().unwrap(),
296 )
297 };
298 status_result(status)
299 }
300
301 fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
302 let mut out = ptr::null_mut();
303 let status = unsafe {
304 // Safety: `SpIBinder` guarantees that `self` always contains a
305 // valid pointer to an `AIBinder`. After this call, the `out`
306 // parameter will be either null, or a valid pointer to an
307 // `AIBinder`.
308 //
309 // This call passes ownership of the out pointer to its caller
310 // (assuming it is set to a non-null value).
311 sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
312 };
313 let ibinder = unsafe {
314 // Safety: The call above guarantees that `out` is either null or a
315 // valid, owned pointer to an `AIBinder`, both of which are safe to
316 // pass to `SpIBinder::from_raw`.
317 SpIBinder::from_raw(out)
318 };
319
320 status_result(status)?;
321 Ok(ibinder)
322 }
323
324 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
325 status_result(unsafe {
326 // Safety: `SpIBinder` guarantees that `self` always contains a
327 // valid pointer to an `AIBinder`. `recipient` can always be
328 // converted into a valid pointer to an
329 // `AIBinder_DeatRecipient`. Any value is safe to pass as the
330 // cookie, although we depend on this value being set by
331 // `get_cookie` when the death recipient callback is called.
332 sys::AIBinder_linkToDeath(
333 self.as_native_mut(),
334 recipient.as_native_mut(),
335 recipient.get_cookie(),
336 )
337 })
338 }
339
340 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
341 status_result(unsafe {
342 // Safety: `SpIBinder` guarantees that `self` always contains a
343 // valid pointer to an `AIBinder`. `recipient` can always be
344 // converted into a valid pointer to an
345 // `AIBinder_DeatRecipient`. Any value is safe to pass as the
346 // cookie, although we depend on this value being set by
347 // `get_cookie` when the death recipient callback is called.
348 sys::AIBinder_unlinkToDeath(
349 self.as_native_mut(),
350 recipient.as_native_mut(),
351 recipient.get_cookie(),
352 )
353 })
354 }
355}
356
357impl Serialize for SpIBinder {
358 fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
359 parcel.write_binder(Some(self))
360 }
361}
362
363impl SerializeOption for SpIBinder {
364 fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
365 parcel.write_binder(this)
366 }
367}
368
369impl SerializeArray for SpIBinder {}
370impl SerializeArray for Option<&SpIBinder> {}
371
372impl Deserialize for SpIBinder {
373 fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
Andrei Homescu32814372020-08-20 15:36:08 -0700374 parcel
375 .read_binder()
376 .transpose()
377 .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700378 }
379}
380
381impl DeserializeOption for SpIBinder {
382 fn deserialize_option(parcel: &Parcel) -> Result<Option<SpIBinder>> {
383 parcel.read_binder()
384 }
385}
386
387impl DeserializeArray for SpIBinder {}
388impl DeserializeArray for Option<SpIBinder> {}
389
390/// A weak reference to a Binder remote object.
391///
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000392/// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
393/// is untyped; typed interface access is implemented by the AIDL compiler.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700394pub struct WpIBinder(*mut sys::AIBinder_Weak);
395
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000396impl fmt::Debug for WpIBinder {
397 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
398 f.pad("WpIBinder")
399 }
400}
401
402/// # Safety
403///
404/// A `WpIBinder` is a handle to a C++ IBinder, which is thread-safe.
405unsafe impl Send for WpIBinder {}
406
Stephen Crane2a3c2502020-06-16 17:48:35 -0700407impl WpIBinder {
408 /// Create a new weak reference from an object that can be converted into a
409 /// raw `AIBinder` pointer.
Andrew Walbran8fe3ecc2020-12-15 11:29:58 +0000410 fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700411 let ptr = unsafe {
412 // Safety: `SpIBinder` guarantees that `binder` always contains a
413 // valid pointer to an `AIBinder`.
414 sys::AIBinder_Weak_new(binder.as_native_mut())
415 };
416 assert!(!ptr.is_null());
417 Self(ptr)
418 }
Stephen Crane994a0f02020-08-11 14:47:29 -0700419
420 /// Promote this weak reference to a strong reference to the binder object.
421 pub fn promote(&self) -> Option<SpIBinder> {
422 unsafe {
423 // Safety: `WpIBinder` always contains a valid weak reference, so we
424 // can pass this pointer to `AIBinder_Weak_promote`. Returns either
425 // null or an AIBinder owned by the caller, both of which are valid
426 // to pass to `SpIBinder::from_raw`.
427 let ptr = sys::AIBinder_Weak_promote(self.0);
428 SpIBinder::from_raw(ptr)
429 }
430 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700431}
432
Andrew Walbran5e8dfa32020-12-16 12:50:06 +0000433impl Drop for WpIBinder {
434 fn drop(&mut self) {
435 unsafe {
436 // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
437 // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
438 sys::AIBinder_Weak_delete(self.0);
439 }
440 }
441}
442
Stephen Crane2a3c2502020-06-16 17:48:35 -0700443/// Rust wrapper around DeathRecipient objects.
444#[repr(C)]
445pub struct DeathRecipient {
446 recipient: *mut sys::AIBinder_DeathRecipient,
447 callback: Box<dyn Fn() + Send + 'static>,
448}
449
450impl DeathRecipient {
451 /// Create a new death recipient that will call the given callback when its
452 /// associated object dies.
453 pub fn new<F>(callback: F) -> DeathRecipient
454 where
455 F: Fn() + Send + 'static,
456 {
457 let callback = Box::new(callback);
458 let recipient = unsafe {
459 // Safety: The function pointer is a valid death recipient callback.
460 //
461 // This call returns an owned `AIBinder_DeathRecipient` pointer
462 // which must be destroyed via `AIBinder_DeathRecipient_delete` when
463 // no longer needed.
464 sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
465 };
466 DeathRecipient {
467 recipient,
468 callback,
469 }
470 }
471
472 /// Get the opaque cookie that identifies this death recipient.
473 ///
474 /// This cookie will be used to link and unlink this death recipient to a
475 /// binder object and will be passed to the `binder_died` callback as an
476 /// opaque userdata pointer.
477 fn get_cookie(&self) -> *mut c_void {
478 &*self.callback as *const _ as *mut c_void
479 }
480
481 /// Callback invoked from C++ when the binder object dies.
482 ///
483 /// # Safety
484 ///
485 /// The `cookie` parameter must have been created with the `get_cookie`
486 /// method of this object.
487 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
488 where
489 F: Fn() + Send + 'static,
490 {
491 let callback = (cookie as *mut F).as_ref().unwrap();
492 callback();
493 }
494}
495
496/// # Safety
497///
498/// A `DeathRecipient` is always constructed with a valid raw pointer to an
499/// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
500/// pointer.
501unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
502 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
503 self.recipient
504 }
505
506 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
507 self.recipient
508 }
509}
510
511impl Drop for DeathRecipient {
512 fn drop(&mut self) {
513 unsafe {
514 // Safety: `self.recipient` is always a valid, owned
515 // `AIBinder_DeathRecipient` pointer returned by
516 // `AIBinder_DeathRecipient_new` when `self` was created. This
517 // delete method can only be called once when `self` is dropped.
518 sys::AIBinder_DeathRecipient_delete(self.recipient);
519 }
520 }
521}
522
523/// Generic interface to remote binder objects.
524///
525/// Corresponds to the C++ `BpInterface` class.
526pub trait Proxy: Sized + Interface {
527 /// The Binder interface descriptor string.
528 ///
529 /// This string is a unique identifier for a Binder interface, and should be
530 /// the same between all implementations of that interface.
531 fn get_descriptor() -> &'static str;
532
533 /// Create a new interface from the given proxy, if it matches the expected
534 /// type of this interface.
535 fn from_binder(binder: SpIBinder) -> Result<Self>;
536}
537
538/// # Safety
539///
540/// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
541/// invocation of `IBinder` methods directly from `Interface` objects. It shares
542/// the same safety as the implementation for `SpIBinder`.
543unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
544 fn as_native(&self) -> *const sys::AIBinder {
545 self.as_binder().as_native()
546 }
547
548 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
549 self.as_binder().as_native_mut()
550 }
551}
552
553/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
554/// exist.
555pub fn get_service(name: &str) -> Option<SpIBinder> {
556 let name = CString::new(name).ok()?;
557 unsafe {
558 // Safety: `AServiceManager_getService` returns either a null pointer or
559 // a valid pointer to an owned `AIBinder`. Either of these values is
560 // safe to pass to `SpIBinder::from_raw`.
561 SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
562 }
563}
564
565/// Retrieve an existing service for a particular interface, blocking for a few
566/// seconds if it doesn't yet exist.
567pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Box<T>> {
568 let service = get_service(name);
569 match service {
570 Some(service) => FromIBinder::try_from(service),
571 None => Err(StatusCode::NAME_NOT_FOUND),
572 }
573}
574
575/// # Safety
576///
577/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
578/// `AIBinder`, so we can trivially extract this pointer here.
579unsafe impl AsNative<sys::AIBinder> for SpIBinder {
580 fn as_native(&self) -> *const sys::AIBinder {
581 self.0
582 }
583
584 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
585 self.0
586 }
587}