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