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