blob: 6186b88eed1ffbd3c2bb651f46edc69bc47288d6 [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//! Trait definitions for binder objects
18
19use crate::error::{status_t, Result};
20use crate::parcel::Parcel;
21use crate::proxy::{DeathRecipient, SpIBinder};
22use crate::sys;
23
24use std::ffi::{c_void, CString};
25use std::os::unix::io::AsRawFd;
26use std::ptr;
27
28/// Binder action to perform.
29///
30/// This must be a number between [`IBinder::FIRST_CALL_TRANSACTION`] and
31/// [`IBinder::LAST_CALL_TRANSACTION`].
32pub type TransactionCode = u32;
33
34/// Additional operation flags.
35///
36/// Can be either 0 for a normal RPC, or [`IBinder::FLAG_ONEWAY`] for a
37/// one-way RPC.
38pub type TransactionFlags = u32;
39
40/// Super-trait for Binder interfaces.
41///
42/// This trait allows conversion of a Binder interface trait object into an
43/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
44/// interfaces) must implement this trait.
45///
46/// This is equivalent `IInterface` in C++.
47pub trait Interface {
48 /// Convert this binder object into a generic [`SpIBinder`] reference.
49 fn as_binder(&self) -> SpIBinder {
50 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
51 }
52}
53
54/// A local service that can be remotable via Binder.
55///
56/// An object that implement this interface made be made into a Binder service
57/// via `Binder::new(object)`.
58///
59/// This is a low-level interface that should normally be automatically
60/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
61/// the AIDL backend, users need only implement the high-level AIDL-defined
62/// interface. The AIDL compiler then generates a container struct that wraps
63/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -070064pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070065 /// The Binder interface descriptor string.
66 ///
67 /// This string is a unique identifier for a Binder interface, and should be
68 /// the same between all implementations of that interface.
69 fn get_descriptor() -> &'static str;
70
71 /// Handle and reply to a request to invoke a transaction on this object.
72 ///
73 /// `reply` may be [`None`] if the sender does not expect a reply.
74 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
75
76 /// Retrieve the class of this remote object.
77 ///
78 /// This method should always return the same InterfaceClass for the same
79 /// type.
80 fn get_class() -> InterfaceClass;
81}
82
83/// Interface of binder local or remote objects.
84///
85/// This trait corresponds to the interface of the C++ `IBinder` class.
86pub trait IBinder {
87 /// First transaction code available for user commands (inclusive)
88 const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
89 /// Last transaction code available for user commands (inclusive)
90 const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
91
92 /// Corresponds to TF_ONE_WAY -- an asynchronous call.
93 const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
94
95 /// Is this object still alive?
96 fn is_binder_alive(&self) -> bool;
97
98 /// Send a ping transaction to this object
99 fn ping_binder(&mut self) -> Result<()>;
100
101 /// Dump this object to the given file handle
102 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
103
104 /// Get a new interface that exposes additional extension functionality, if
105 /// available.
106 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
107
108 /// Perform a generic operation with the object.
109 ///
110 /// # Arguments
111 /// * `code` - Transaction code for the operation
112 /// * `data` - [`Parcel`] with input data
113 /// * `reply` - Optional [`Parcel`] for reply data
114 /// * `flags` - Transaction flags, e.g. marking the transaction as
115 /// asynchronous ([`FLAG_ONEWAY`](IBinder::FLAG_ONEWAY))
116 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
117 &self,
118 code: TransactionCode,
119 flags: TransactionFlags,
120 input_callback: F,
121 ) -> Result<Parcel>;
122
123 /// Register the recipient for a notification if this binder
124 /// goes away. If this binder object unexpectedly goes away
125 /// (typically because its hosting process has been killed),
126 /// then DeathRecipient::binder_died() will be called with a reference
127 /// to this.
128 ///
129 /// You will only receive death notifications for remote binders,
130 /// as local binders by definition can't die without you dying as well.
131 /// Trying to use this function on a local binder will result in an
132 /// INVALID_OPERATION code being returned and nothing happening.
133 ///
134 /// This link always holds a weak reference to its recipient.
135 ///
136 /// You will only receive a weak reference to the dead
137 /// binder. You should not try to promote this to a strong reference.
138 /// (Nor should you need to, as there is nothing useful you can
139 /// directly do with it now that it has passed on.)
140 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
141
142 /// Remove a previously registered death notification.
143 /// The recipient will no longer be called if this object
144 /// dies.
145 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
146}
147
148/// Opaque reference to the type of a Binder interface.
149///
150/// This object encapsulates the Binder interface descriptor string, along with
151/// the binder transaction callback, if the class describes a local service.
152///
153/// A Binder remotable object may only have a single interface class, and any
154/// given object can only be associated with one class. Two objects with
155/// different classes are incompatible, even if both classes have the same
156/// interface descriptor.
157#[derive(Copy, Clone, PartialEq, Eq)]
158pub struct InterfaceClass(*const sys::AIBinder_Class);
159
160impl InterfaceClass {
161 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
162 ///
163 /// Note: the returned pointer will not be constant. Calling this method
164 /// multiple times for the same type will result in distinct class
165 /// pointers. A static getter for this value is implemented in
166 /// [`declare_binder_interface!`].
167 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
168 let descriptor = CString::new(I::get_descriptor()).unwrap();
169 let ptr = unsafe {
170 // Safety: `AIBinder_Class_define` expects a valid C string, and
171 // three valid callback functions, all non-null pointers. The C
172 // string is copied and need not be valid for longer than the call,
173 // so we can drop it after the call. We can safely assign null to
174 // the onDump and handleShellCommand callbacks as long as the class
175 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
176 // be a NULL pointer. Rust retains ownership of the pointer after it
177 // is defined.
178 let class = sys::AIBinder_Class_define(
179 descriptor.as_ptr(),
180 Some(I::on_create),
181 Some(I::on_destroy),
182 Some(I::on_transact),
183 );
184 if class.is_null() {
185 panic!("Expected non-null class pointer from AIBinder_Class_define!");
186 }
187 sys::AIBinder_Class_setOnDump(class, None);
188 sys::AIBinder_Class_setHandleShellCommand(class, None);
189 class
190 };
191 InterfaceClass(ptr)
192 }
193
194 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
195 /// pointer.
196 ///
197 /// # Safety
198 ///
199 /// This function is safe iff `ptr` is a valid, non-null pointer to an
200 /// `AIBinder_Class`.
201 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
202 InterfaceClass(ptr)
203 }
204}
205
206impl From<InterfaceClass> for *const sys::AIBinder_Class {
207 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
208 class.0
209 }
210}
211
212/// Create a function implementing a static getter for an interface class.
213///
214/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
215/// [`Interface`]) must have global, static class that uniquely identifies
216/// it. This macro implements an [`InterfaceClass`] getter to simplify these
217/// implementations.
218///
219/// The type of a structure that implements [`InterfaceClassMethods`] must be
220/// passed to this macro. For local services, this should be `Binder<Self>`
221/// since [`Binder`] implements [`InterfaceClassMethods`].
222///
223/// # Examples
224///
225/// When implementing a local [`Remotable`] service `ExampleService`, the
226/// `get_class` method is required in the [`Remotable`] impl block. This macro
227/// should be used as follows to implement this functionality:
228///
229/// ```rust
230/// impl Remotable for ExampleService {
231/// fn get_descriptor() -> &'static str {
232/// "android.os.IExampleInterface"
233/// }
234///
235/// fn on_transact(
236/// &self,
237/// code: TransactionCode,
238/// data: &Parcel,
239/// reply: &mut Parcel,
240/// ) -> Result<()> {
241/// // ...
242/// }
243///
244/// binder_fn_get_class!(Binder<Self>);
245/// }
246/// ```
247macro_rules! binder_fn_get_class {
248 ($class:ty) => {
249 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
250 };
251
252 ($constructor:expr) => {
253 fn get_class() -> $crate::InterfaceClass {
254 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
255 static mut CLASS: Option<$crate::InterfaceClass> = None;
256
257 CLASS_INIT.call_once(|| unsafe {
258 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
259 // variable, and therefore is thread-safe, as it can only occur
260 // once.
261 CLASS = Some($constructor);
262 });
263 unsafe {
264 // Safety: The `CLASS` variable can only be mutated once, above,
265 // and is subsequently safe to read from any thread.
266 CLASS.unwrap()
267 }
268 }
269 };
270}
271
272pub trait InterfaceClassMethods {
273 /// Get the interface descriptor string for this object type.
274 fn get_descriptor() -> &'static str
275 where
276 Self: Sized;
277
278 /// Called during construction of a new `AIBinder` object of this interface
279 /// class.
280 ///
281 /// The opaque pointer parameter will be the parameter provided to
282 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
283 /// `AIBinder` object.
284 ///
285 /// # Safety
286 ///
287 /// Callback called from C++. The parameter argument provided to
288 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
289 /// will take ownership of the returned pointer, which it will free via
290 /// `on_destroy`.
291 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
292
293 /// Called when a transaction needs to be processed by the local service
294 /// implementation.
295 ///
296 /// # Safety
297 ///
298 /// Callback called from C++. The `binder` parameter must be a valid pointer
299 /// to a binder object of this class with userdata initialized via this
300 /// class's `on_create`. The parcel parameters must be valid pointers to
301 /// parcel objects.
302 unsafe extern "C" fn on_transact(
303 binder: *mut sys::AIBinder,
304 code: u32,
305 data: *const sys::AParcel,
306 reply: *mut sys::AParcel,
307 ) -> status_t;
308
309 /// Called whenever an `AIBinder` object is no longer referenced and needs
310 /// to be destroyed.
311 ///
312 /// # Safety
313 ///
314 /// Callback called from C++. The opaque pointer parameter must be the value
315 /// returned by `on_create` for this class. This function takes ownership of
316 /// the provided pointer and destroys it.
317 unsafe extern "C" fn on_destroy(object: *mut c_void);
318}
319
320/// Interface for transforming a generic SpIBinder into a specific remote
321/// interface trait.
322///
323/// # Example
324///
325/// For Binder interface `IFoo`, the following implementation should be made:
326/// ```no_run
327/// # use binder::{FromIBinder, SpIBinder, Result};
328/// # trait IFoo {}
329/// impl FromIBinder for dyn IFoo {
330/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
331/// // ...
332/// # Err(binder::StatusCode::OK)
333/// }
334/// }
335/// ```
336pub trait FromIBinder {
337 /// Try to interpret a generic Binder object as this interface.
338 ///
339 /// Returns a trait object for the `Self` interface if this object
340 /// implements that interface.
341 fn try_from(ibinder: SpIBinder) -> Result<Box<Self>>;
342}
343
344/// Trait for transparent Rust wrappers around android C++ native types.
345///
346/// The pointer return by this trait's methods should be immediately passed to
347/// C++ and not stored by Rust. The pointer is valid only as long as the
348/// underlying C++ object is alive, so users must be careful to take this into
349/// account, as Rust cannot enforce this.
350///
351/// # Safety
352///
353/// For this trait to be a correct implementation, `T` must be a valid android
354/// C++ type. Since we cannot constrain this via the type system, this trait is
355/// marked as unsafe.
356pub unsafe trait AsNative<T> {
357 /// Return a pointer to the native version of `self`
358 fn as_native(&self) -> *const T;
359
360 /// Return a mutable pointer to the native version of `self`
361 fn as_native_mut(&mut self) -> *mut T;
362}
363
364unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
365 fn as_native(&self) -> *const T {
366 self.as_ref().map_or(ptr::null(), |v| v.as_native())
367 }
368
369 fn as_native_mut(&mut self) -> *mut T {
370 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
371 }
372}
373
374/// Declare typed interfaces for a binder object.
375///
376/// Given an interface trait and descriptor string, create a native and remote
377/// proxy wrapper for this interface. The native service object (`$native`)
378/// implements `Remotable` and will dispatch to the function `$on_transact` to
379/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
380/// objects for this interface and can optionally contain additional fields.
381///
382/// Assuming the interface trait is `Interface`, `$on_transact` function must
383/// have the following type:
384///
385/// ```
386/// # use binder::{Interface, TransactionCode, Parcel};
387/// # trait Placeholder {
388/// fn on_transact(
389/// service: &dyn Interface,
390/// code: TransactionCode,
391/// data: &Parcel,
392/// reply: &mut Parcel,
393/// ) -> binder::Result<()>;
394/// # }
395/// ```
396///
397/// # Examples
398///
399/// The following example declares the local service type `BnServiceManager` and
400/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
401/// proxy respectively) for the `IServiceManager` Binder interface. The
402/// interfaces will be identified by the descriptor string
403/// "android.os.IServiceManager". The local service will dispatch transactions
404/// using the provided function, `on_transact`.
405///
406/// ```
407/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
408///
409/// pub trait IServiceManager: Interface {
410/// // remote methods...
411/// }
412///
413/// declare_binder_interface! {
414/// IServiceManager["android.os.IServiceManager"] {
415/// native: BnServiceManager(on_transact),
416/// proxy: BpServiceManager,
417/// }
418/// }
419///
420/// fn on_transact(
421/// service: &dyn IServiceManager,
422/// code: TransactionCode,
423/// data: &Parcel,
424/// reply: &mut Parcel,
425/// ) -> binder::Result<()> {
426/// // ...
427/// Ok(())
428/// }
429///
430/// impl IServiceManager for BpServiceManager {
431/// // parceling/unparceling code for the IServiceManager emitted here
432/// }
433///
434/// impl IServiceManager for Binder<BnServiceManager> {
435/// // Forward calls to local implementation
436/// }
437/// ```
438#[macro_export]
439macro_rules! declare_binder_interface {
440 {
441 $interface:path[$descriptor:expr] {
442 native: $native:ident($on_transact:path),
443 proxy: $proxy:ident,
444 }
445 } => {
446 $crate::declare_binder_interface! {
447 $interface[$descriptor] {
448 native: $native($on_transact),
449 proxy: $proxy {},
450 }
451 }
452 };
453
454 {
455 $interface:path[$descriptor:expr] {
456 native: $native:ident($on_transact:path),
457 proxy: $proxy:ident {
458 $($fname:ident: $fty:ty = $finit:expr),*
459 },
460 }
461 } => {
462 $crate::declare_binder_interface! {
463 $interface[$descriptor] {
464 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
465 native: $native($on_transact),
466 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
467 proxy: $proxy {
468 $($fname: $fty = $finit),*
469 },
470 }
471 }
472 };
473
474 {
475 $interface:path[$descriptor:expr] {
476 @doc[$native_doc:expr]
477 native: $native:ident($on_transact:path),
478
479 @doc[$proxy_doc:expr]
480 proxy: $proxy:ident {
481 $($fname:ident: $fty:ty = $finit:expr),*
482 },
483 }
484 } => {
485 #[doc = $proxy_doc]
486 pub struct $proxy {
487 binder: $crate::SpIBinder,
488 $($fname: $fty,)*
489 }
490
491 impl $crate::Interface for $proxy {
492 fn as_binder(&self) -> $crate::SpIBinder {
493 self.binder.clone()
494 }
495 }
496
497 impl $crate::Proxy for $proxy
498 where
499 $proxy: $interface,
500 {
501 fn get_descriptor() -> &'static str {
502 $descriptor
503 }
504
505 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
506 use $crate::AssociateClass;
507 if binder.associate_class(<$native as $crate::Remotable>::get_class()) {
508 Ok(Self { binder, $($fname: $finit),* })
509 } else {
510 Err($crate::StatusCode::BAD_TYPE)
511 }
512 }
513 }
514
515 #[doc = $native_doc]
516 #[repr(transparent)]
517 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
518
519 impl $native {
520 /// Create a new binder service.
521 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> impl $interface {
522 $crate::Binder::new($native(Box::new(inner)))
523 }
524 }
525
526 impl $crate::Remotable for $native {
527 fn get_descriptor() -> &'static str {
528 $descriptor
529 }
530
531 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700532 match $on_transact(&*self.0, code, data, reply) {
533 // The C++ backend converts UNEXPECTED_NULL into an exception
534 Err($crate::StatusCode::UNEXPECTED_NULL) => {
535 let status = $crate::Status::new_exception(
536 $crate::ExceptionCode::NULL_POINTER,
537 None,
538 );
539 reply.write(&status)
540 },
541 result => result
542 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700543 }
544
545 fn get_class() -> $crate::InterfaceClass {
546 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
547 static mut CLASS: Option<$crate::InterfaceClass> = None;
548
549 CLASS_INIT.call_once(|| unsafe {
550 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
551 // variable, and therefore is thread-safe, as it can only occur
552 // once.
553 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
554 });
555 unsafe {
556 // Safety: The `CLASS` variable can only be mutated once, above,
557 // and is subsequently safe to read from any thread.
558 CLASS.unwrap()
559 }
560 }
561 }
562
563 impl $crate::FromIBinder for dyn $interface {
564 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
565 use $crate::AssociateClass;
566 if !ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
567 return Err($crate::StatusCode::BAD_TYPE.into());
568 }
569
570 let service: $crate::Result<$crate::Binder<$native>> = std::convert::TryFrom::try_from(ibinder.clone());
571 if let Ok(service) = service {
572 Ok(Box::new(service))
573 } else {
574 Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))
575 }
576 }
577 }
578
579 impl $crate::parcel::Serialize for dyn $interface + '_
580 where
581 $interface: $crate::Interface
582 {
583 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
584 let binder = $crate::Interface::as_binder(self);
585 parcel.write(&binder)
586 }
587 }
588
589 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
590 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
591 parcel.write(&this.map($crate::Interface::as_binder))
592 }
593 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700594
595 impl std::fmt::Debug for dyn $interface {
596 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
597 f.pad(stringify!($interface))
598 }
599 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700600 };
601}
Andrei Homescu00eca712020-09-09 18:57:40 -0700602
603/// Declare an AIDL enumeration.
604///
605/// This is mainly used internally by the AIDL compiler.
606#[macro_export]
607macro_rules! declare_binder_enum {
608 {
609 $enum:ident : $backing:ty {
610 $( $name:ident = $value:expr, )*
611 }
612 } => {
613 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
614 pub struct $enum(pub $backing);
615 impl $enum {
616 $( pub const $name: Self = Self($value); )*
617 }
618
619 impl $crate::parcel::Serialize for $enum {
620 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
621 parcel.write(&self.0)
622 }
623 }
624
625 impl $crate::parcel::SerializeArray for $enum {
626 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
627 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
628 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
629 }
630 }
631
632 impl $crate::parcel::Deserialize for $enum {
633 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
634 parcel.read().map(Self)
635 }
636 }
637
638 impl $crate::parcel::DeserializeArray for $enum {
639 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
640 let v: Option<Vec<$backing>> =
641 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
642 Ok(v.map(|v| v.into_iter().map(Self).collect()))
643 }
644 }
645 };
646}