blob: 5602c9688c35778fa2480c0c0488816d84f65864 [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.
94 pub(crate) fn get_class(&mut self) -> Option<InterfaceClass> {
95 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
252 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
253 let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
254 let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
255 let status = unsafe {
256 // Safety: `SpIBinder` guarantees that `self` always contains a
257 // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
258 // file descriptor parameter is always be a valid open file. The
259 // `args` pointer parameter is a valid pointer to an array of C
260 // strings that will outlive the call since `args` lives for the
261 // whole function scope.
262 //
263 // This call does not affect ownership of its binder pointer
264 // parameter and does not take ownership of the file or args array
265 // parameters.
266 sys::AIBinder_dump(
267 self.as_native_mut(),
268 fp.as_raw_fd(),
269 arg_ptrs.as_mut_ptr(),
270 arg_ptrs.len().try_into().unwrap(),
271 )
272 };
273 status_result(status)
274 }
275
276 fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
277 let mut out = ptr::null_mut();
278 let status = unsafe {
279 // Safety: `SpIBinder` guarantees that `self` always contains a
280 // valid pointer to an `AIBinder`. After this call, the `out`
281 // parameter will be either null, or a valid pointer to an
282 // `AIBinder`.
283 //
284 // This call passes ownership of the out pointer to its caller
285 // (assuming it is set to a non-null value).
286 sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
287 };
288 let ibinder = unsafe {
289 // Safety: The call above guarantees that `out` is either null or a
290 // valid, owned pointer to an `AIBinder`, both of which are safe to
291 // pass to `SpIBinder::from_raw`.
292 SpIBinder::from_raw(out)
293 };
294
295 status_result(status)?;
296 Ok(ibinder)
297 }
298
299 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
300 status_result(unsafe {
301 // Safety: `SpIBinder` guarantees that `self` always contains a
302 // valid pointer to an `AIBinder`. `recipient` can always be
303 // converted into a valid pointer to an
304 // `AIBinder_DeatRecipient`. Any value is safe to pass as the
305 // cookie, although we depend on this value being set by
306 // `get_cookie` when the death recipient callback is called.
307 sys::AIBinder_linkToDeath(
308 self.as_native_mut(),
309 recipient.as_native_mut(),
310 recipient.get_cookie(),
311 )
312 })
313 }
314
315 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
316 status_result(unsafe {
317 // Safety: `SpIBinder` guarantees that `self` always contains a
318 // valid pointer to an `AIBinder`. `recipient` can always be
319 // converted into a valid pointer to an
320 // `AIBinder_DeatRecipient`. Any value is safe to pass as the
321 // cookie, although we depend on this value being set by
322 // `get_cookie` when the death recipient callback is called.
323 sys::AIBinder_unlinkToDeath(
324 self.as_native_mut(),
325 recipient.as_native_mut(),
326 recipient.get_cookie(),
327 )
328 })
329 }
330}
331
332impl Serialize for SpIBinder {
333 fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
334 parcel.write_binder(Some(self))
335 }
336}
337
338impl SerializeOption for SpIBinder {
339 fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
340 parcel.write_binder(this)
341 }
342}
343
344impl SerializeArray for SpIBinder {}
345impl SerializeArray for Option<&SpIBinder> {}
346
347impl Deserialize for SpIBinder {
348 fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
349 parcel.read_binder().transpose().unwrap()
350 }
351}
352
353impl DeserializeOption for SpIBinder {
354 fn deserialize_option(parcel: &Parcel) -> Result<Option<SpIBinder>> {
355 parcel.read_binder()
356 }
357}
358
359impl DeserializeArray for SpIBinder {}
360impl DeserializeArray for Option<SpIBinder> {}
361
362/// A weak reference to a Binder remote object.
363///
364/// This struct encapsulates the C++ `wp<IBinder>` class. However, this wrapper
365/// is untyped, so properly typed versions implementing a particular binder
366/// interface should be crated with [`declare_binder_interface!`].
367pub struct WpIBinder(*mut sys::AIBinder_Weak);
368
369impl WpIBinder {
370 /// Create a new weak reference from an object that can be converted into a
371 /// raw `AIBinder` pointer.
372 pub fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
373 let ptr = unsafe {
374 // Safety: `SpIBinder` guarantees that `binder` always contains a
375 // valid pointer to an `AIBinder`.
376 sys::AIBinder_Weak_new(binder.as_native_mut())
377 };
378 assert!(!ptr.is_null());
379 Self(ptr)
380 }
Stephen Crane994a0f02020-08-11 14:47:29 -0700381
382 /// Promote this weak reference to a strong reference to the binder object.
383 pub fn promote(&self) -> Option<SpIBinder> {
384 unsafe {
385 // Safety: `WpIBinder` always contains a valid weak reference, so we
386 // can pass this pointer to `AIBinder_Weak_promote`. Returns either
387 // null or an AIBinder owned by the caller, both of which are valid
388 // to pass to `SpIBinder::from_raw`.
389 let ptr = sys::AIBinder_Weak_promote(self.0);
390 SpIBinder::from_raw(ptr)
391 }
392 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700393}
394
395/// Rust wrapper around DeathRecipient objects.
396#[repr(C)]
397pub struct DeathRecipient {
398 recipient: *mut sys::AIBinder_DeathRecipient,
399 callback: Box<dyn Fn() + Send + 'static>,
400}
401
402impl DeathRecipient {
403 /// Create a new death recipient that will call the given callback when its
404 /// associated object dies.
405 pub fn new<F>(callback: F) -> DeathRecipient
406 where
407 F: Fn() + Send + 'static,
408 {
409 let callback = Box::new(callback);
410 let recipient = unsafe {
411 // Safety: The function pointer is a valid death recipient callback.
412 //
413 // This call returns an owned `AIBinder_DeathRecipient` pointer
414 // which must be destroyed via `AIBinder_DeathRecipient_delete` when
415 // no longer needed.
416 sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
417 };
418 DeathRecipient {
419 recipient,
420 callback,
421 }
422 }
423
424 /// Get the opaque cookie that identifies this death recipient.
425 ///
426 /// This cookie will be used to link and unlink this death recipient to a
427 /// binder object and will be passed to the `binder_died` callback as an
428 /// opaque userdata pointer.
429 fn get_cookie(&self) -> *mut c_void {
430 &*self.callback as *const _ as *mut c_void
431 }
432
433 /// Callback invoked from C++ when the binder object dies.
434 ///
435 /// # Safety
436 ///
437 /// The `cookie` parameter must have been created with the `get_cookie`
438 /// method of this object.
439 unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
440 where
441 F: Fn() + Send + 'static,
442 {
443 let callback = (cookie as *mut F).as_ref().unwrap();
444 callback();
445 }
446}
447
448/// # Safety
449///
450/// A `DeathRecipient` is always constructed with a valid raw pointer to an
451/// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
452/// pointer.
453unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
454 fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
455 self.recipient
456 }
457
458 fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
459 self.recipient
460 }
461}
462
463impl Drop for DeathRecipient {
464 fn drop(&mut self) {
465 unsafe {
466 // Safety: `self.recipient` is always a valid, owned
467 // `AIBinder_DeathRecipient` pointer returned by
468 // `AIBinder_DeathRecipient_new` when `self` was created. This
469 // delete method can only be called once when `self` is dropped.
470 sys::AIBinder_DeathRecipient_delete(self.recipient);
471 }
472 }
473}
474
475/// Generic interface to remote binder objects.
476///
477/// Corresponds to the C++ `BpInterface` class.
478pub trait Proxy: Sized + Interface {
479 /// The Binder interface descriptor string.
480 ///
481 /// This string is a unique identifier for a Binder interface, and should be
482 /// the same between all implementations of that interface.
483 fn get_descriptor() -> &'static str;
484
485 /// Create a new interface from the given proxy, if it matches the expected
486 /// type of this interface.
487 fn from_binder(binder: SpIBinder) -> Result<Self>;
488}
489
490/// # Safety
491///
492/// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
493/// invocation of `IBinder` methods directly from `Interface` objects. It shares
494/// the same safety as the implementation for `SpIBinder`.
495unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
496 fn as_native(&self) -> *const sys::AIBinder {
497 self.as_binder().as_native()
498 }
499
500 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
501 self.as_binder().as_native_mut()
502 }
503}
504
505/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
506/// exist.
507pub fn get_service(name: &str) -> Option<SpIBinder> {
508 let name = CString::new(name).ok()?;
509 unsafe {
510 // Safety: `AServiceManager_getService` returns either a null pointer or
511 // a valid pointer to an owned `AIBinder`. Either of these values is
512 // safe to pass to `SpIBinder::from_raw`.
513 SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
514 }
515}
516
517/// Retrieve an existing service for a particular interface, blocking for a few
518/// seconds if it doesn't yet exist.
519pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Box<T>> {
520 let service = get_service(name);
521 match service {
522 Some(service) => FromIBinder::try_from(service),
523 None => Err(StatusCode::NAME_NOT_FOUND),
524 }
525}
526
527/// # Safety
528///
529/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
530/// `AIBinder`, so we can trivially extract this pointer here.
531unsafe impl AsNative<sys::AIBinder> for SpIBinder {
532 fn as_native(&self) -> *const sys::AIBinder {
533 self.0
534 }
535
536 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
537 self.0
538 }
539}