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