blob: d8e0609ab70bc0783218f90caab90e8c7bde4f72 [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
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700101 /// Indicate that the service intends to receive caller security contexts.
102 fn set_requesting_sid(&mut self, enable: bool);
103
Stephen Crane2a3c2502020-06-16 17:48:35 -0700104 /// Dump this object to the given file handle
105 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
106
107 /// Get a new interface that exposes additional extension functionality, if
108 /// available.
109 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
110
111 /// Perform a generic operation with the object.
112 ///
113 /// # Arguments
114 /// * `code` - Transaction code for the operation
115 /// * `data` - [`Parcel`] with input data
116 /// * `reply` - Optional [`Parcel`] for reply data
117 /// * `flags` - Transaction flags, e.g. marking the transaction as
118 /// asynchronous ([`FLAG_ONEWAY`](IBinder::FLAG_ONEWAY))
119 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
120 &self,
121 code: TransactionCode,
122 flags: TransactionFlags,
123 input_callback: F,
124 ) -> Result<Parcel>;
125
126 /// Register the recipient for a notification if this binder
127 /// goes away. If this binder object unexpectedly goes away
128 /// (typically because its hosting process has been killed),
129 /// then DeathRecipient::binder_died() will be called with a reference
130 /// to this.
131 ///
132 /// You will only receive death notifications for remote binders,
133 /// as local binders by definition can't die without you dying as well.
134 /// Trying to use this function on a local binder will result in an
135 /// INVALID_OPERATION code being returned and nothing happening.
136 ///
137 /// This link always holds a weak reference to its recipient.
138 ///
139 /// You will only receive a weak reference to the dead
140 /// binder. You should not try to promote this to a strong reference.
141 /// (Nor should you need to, as there is nothing useful you can
142 /// directly do with it now that it has passed on.)
143 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
144
145 /// Remove a previously registered death notification.
146 /// The recipient will no longer be called if this object
147 /// dies.
148 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
149}
150
151/// Opaque reference to the type of a Binder interface.
152///
153/// This object encapsulates the Binder interface descriptor string, along with
154/// the binder transaction callback, if the class describes a local service.
155///
156/// A Binder remotable object may only have a single interface class, and any
157/// given object can only be associated with one class. Two objects with
158/// different classes are incompatible, even if both classes have the same
159/// interface descriptor.
160#[derive(Copy, Clone, PartialEq, Eq)]
161pub struct InterfaceClass(*const sys::AIBinder_Class);
162
163impl InterfaceClass {
164 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
165 ///
166 /// Note: the returned pointer will not be constant. Calling this method
167 /// multiple times for the same type will result in distinct class
168 /// pointers. A static getter for this value is implemented in
169 /// [`declare_binder_interface!`].
170 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
171 let descriptor = CString::new(I::get_descriptor()).unwrap();
172 let ptr = unsafe {
173 // Safety: `AIBinder_Class_define` expects a valid C string, and
174 // three valid callback functions, all non-null pointers. The C
175 // string is copied and need not be valid for longer than the call,
176 // so we can drop it after the call. We can safely assign null to
177 // the onDump and handleShellCommand callbacks as long as the class
178 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
179 // be a NULL pointer. Rust retains ownership of the pointer after it
180 // is defined.
181 let class = sys::AIBinder_Class_define(
182 descriptor.as_ptr(),
183 Some(I::on_create),
184 Some(I::on_destroy),
185 Some(I::on_transact),
186 );
187 if class.is_null() {
188 panic!("Expected non-null class pointer from AIBinder_Class_define!");
189 }
190 sys::AIBinder_Class_setOnDump(class, None);
191 sys::AIBinder_Class_setHandleShellCommand(class, None);
192 class
193 };
194 InterfaceClass(ptr)
195 }
196
197 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
198 /// pointer.
199 ///
200 /// # Safety
201 ///
202 /// This function is safe iff `ptr` is a valid, non-null pointer to an
203 /// `AIBinder_Class`.
204 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
205 InterfaceClass(ptr)
206 }
207}
208
209impl From<InterfaceClass> for *const sys::AIBinder_Class {
210 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
211 class.0
212 }
213}
214
215/// Create a function implementing a static getter for an interface class.
216///
217/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
218/// [`Interface`]) must have global, static class that uniquely identifies
219/// it. This macro implements an [`InterfaceClass`] getter to simplify these
220/// implementations.
221///
222/// The type of a structure that implements [`InterfaceClassMethods`] must be
223/// passed to this macro. For local services, this should be `Binder<Self>`
224/// since [`Binder`] implements [`InterfaceClassMethods`].
225///
226/// # Examples
227///
228/// When implementing a local [`Remotable`] service `ExampleService`, the
229/// `get_class` method is required in the [`Remotable`] impl block. This macro
230/// should be used as follows to implement this functionality:
231///
232/// ```rust
233/// impl Remotable for ExampleService {
234/// fn get_descriptor() -> &'static str {
235/// "android.os.IExampleInterface"
236/// }
237///
238/// fn on_transact(
239/// &self,
240/// code: TransactionCode,
241/// data: &Parcel,
242/// reply: &mut Parcel,
243/// ) -> Result<()> {
244/// // ...
245/// }
246///
247/// binder_fn_get_class!(Binder<Self>);
248/// }
249/// ```
250macro_rules! binder_fn_get_class {
251 ($class:ty) => {
252 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
253 };
254
255 ($constructor:expr) => {
256 fn get_class() -> $crate::InterfaceClass {
257 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
258 static mut CLASS: Option<$crate::InterfaceClass> = None;
259
260 CLASS_INIT.call_once(|| unsafe {
261 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
262 // variable, and therefore is thread-safe, as it can only occur
263 // once.
264 CLASS = Some($constructor);
265 });
266 unsafe {
267 // Safety: The `CLASS` variable can only be mutated once, above,
268 // and is subsequently safe to read from any thread.
269 CLASS.unwrap()
270 }
271 }
272 };
273}
274
275pub trait InterfaceClassMethods {
276 /// Get the interface descriptor string for this object type.
277 fn get_descriptor() -> &'static str
278 where
279 Self: Sized;
280
281 /// Called during construction of a new `AIBinder` object of this interface
282 /// class.
283 ///
284 /// The opaque pointer parameter will be the parameter provided to
285 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
286 /// `AIBinder` object.
287 ///
288 /// # Safety
289 ///
290 /// Callback called from C++. The parameter argument provided to
291 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
292 /// will take ownership of the returned pointer, which it will free via
293 /// `on_destroy`.
294 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
295
296 /// Called when a transaction needs to be processed by the local service
297 /// implementation.
298 ///
299 /// # Safety
300 ///
301 /// Callback called from C++. The `binder` parameter must be a valid pointer
302 /// to a binder object of this class with userdata initialized via this
303 /// class's `on_create`. The parcel parameters must be valid pointers to
304 /// parcel objects.
305 unsafe extern "C" fn on_transact(
306 binder: *mut sys::AIBinder,
307 code: u32,
308 data: *const sys::AParcel,
309 reply: *mut sys::AParcel,
310 ) -> status_t;
311
312 /// Called whenever an `AIBinder` object is no longer referenced and needs
313 /// to be destroyed.
314 ///
315 /// # Safety
316 ///
317 /// Callback called from C++. The opaque pointer parameter must be the value
318 /// returned by `on_create` for this class. This function takes ownership of
319 /// the provided pointer and destroys it.
320 unsafe extern "C" fn on_destroy(object: *mut c_void);
321}
322
323/// Interface for transforming a generic SpIBinder into a specific remote
324/// interface trait.
325///
326/// # Example
327///
328/// For Binder interface `IFoo`, the following implementation should be made:
329/// ```no_run
330/// # use binder::{FromIBinder, SpIBinder, Result};
331/// # trait IFoo {}
332/// impl FromIBinder for dyn IFoo {
333/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
334/// // ...
335/// # Err(binder::StatusCode::OK)
336/// }
337/// }
338/// ```
339pub trait FromIBinder {
340 /// Try to interpret a generic Binder object as this interface.
341 ///
342 /// Returns a trait object for the `Self` interface if this object
343 /// implements that interface.
344 fn try_from(ibinder: SpIBinder) -> Result<Box<Self>>;
345}
346
347/// Trait for transparent Rust wrappers around android C++ native types.
348///
349/// The pointer return by this trait's methods should be immediately passed to
350/// C++ and not stored by Rust. The pointer is valid only as long as the
351/// underlying C++ object is alive, so users must be careful to take this into
352/// account, as Rust cannot enforce this.
353///
354/// # Safety
355///
356/// For this trait to be a correct implementation, `T` must be a valid android
357/// C++ type. Since we cannot constrain this via the type system, this trait is
358/// marked as unsafe.
359pub unsafe trait AsNative<T> {
360 /// Return a pointer to the native version of `self`
361 fn as_native(&self) -> *const T;
362
363 /// Return a mutable pointer to the native version of `self`
364 fn as_native_mut(&mut self) -> *mut T;
365}
366
367unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
368 fn as_native(&self) -> *const T {
369 self.as_ref().map_or(ptr::null(), |v| v.as_native())
370 }
371
372 fn as_native_mut(&mut self) -> *mut T {
373 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
374 }
375}
376
377/// Declare typed interfaces for a binder object.
378///
379/// Given an interface trait and descriptor string, create a native and remote
380/// proxy wrapper for this interface. The native service object (`$native`)
381/// implements `Remotable` and will dispatch to the function `$on_transact` to
382/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
383/// objects for this interface and can optionally contain additional fields.
384///
385/// Assuming the interface trait is `Interface`, `$on_transact` function must
386/// have the following type:
387///
388/// ```
389/// # use binder::{Interface, TransactionCode, Parcel};
390/// # trait Placeholder {
391/// fn on_transact(
392/// service: &dyn Interface,
393/// code: TransactionCode,
394/// data: &Parcel,
395/// reply: &mut Parcel,
396/// ) -> binder::Result<()>;
397/// # }
398/// ```
399///
400/// # Examples
401///
402/// The following example declares the local service type `BnServiceManager` and
403/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
404/// proxy respectively) for the `IServiceManager` Binder interface. The
405/// interfaces will be identified by the descriptor string
406/// "android.os.IServiceManager". The local service will dispatch transactions
407/// using the provided function, `on_transact`.
408///
409/// ```
410/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
411///
412/// pub trait IServiceManager: Interface {
413/// // remote methods...
414/// }
415///
416/// declare_binder_interface! {
417/// IServiceManager["android.os.IServiceManager"] {
418/// native: BnServiceManager(on_transact),
419/// proxy: BpServiceManager,
420/// }
421/// }
422///
423/// fn on_transact(
424/// service: &dyn IServiceManager,
425/// code: TransactionCode,
426/// data: &Parcel,
427/// reply: &mut Parcel,
428/// ) -> binder::Result<()> {
429/// // ...
430/// Ok(())
431/// }
432///
433/// impl IServiceManager for BpServiceManager {
434/// // parceling/unparceling code for the IServiceManager emitted here
435/// }
436///
437/// impl IServiceManager for Binder<BnServiceManager> {
438/// // Forward calls to local implementation
439/// }
440/// ```
441#[macro_export]
442macro_rules! declare_binder_interface {
443 {
444 $interface:path[$descriptor:expr] {
445 native: $native:ident($on_transact:path),
446 proxy: $proxy:ident,
447 }
448 } => {
449 $crate::declare_binder_interface! {
450 $interface[$descriptor] {
451 native: $native($on_transact),
452 proxy: $proxy {},
453 }
454 }
455 };
456
457 {
458 $interface:path[$descriptor:expr] {
459 native: $native:ident($on_transact:path),
460 proxy: $proxy:ident {
461 $($fname:ident: $fty:ty = $finit:expr),*
462 },
463 }
464 } => {
465 $crate::declare_binder_interface! {
466 $interface[$descriptor] {
467 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
468 native: $native($on_transact),
469 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
470 proxy: $proxy {
471 $($fname: $fty = $finit),*
472 },
473 }
474 }
475 };
476
477 {
478 $interface:path[$descriptor:expr] {
479 @doc[$native_doc:expr]
480 native: $native:ident($on_transact:path),
481
482 @doc[$proxy_doc:expr]
483 proxy: $proxy:ident {
484 $($fname:ident: $fty:ty = $finit:expr),*
485 },
486 }
487 } => {
488 #[doc = $proxy_doc]
489 pub struct $proxy {
490 binder: $crate::SpIBinder,
491 $($fname: $fty,)*
492 }
493
494 impl $crate::Interface for $proxy {
495 fn as_binder(&self) -> $crate::SpIBinder {
496 self.binder.clone()
497 }
498 }
499
500 impl $crate::Proxy for $proxy
501 where
502 $proxy: $interface,
503 {
504 fn get_descriptor() -> &'static str {
505 $descriptor
506 }
507
508 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
509 use $crate::AssociateClass;
510 if binder.associate_class(<$native as $crate::Remotable>::get_class()) {
511 Ok(Self { binder, $($fname: $finit),* })
512 } else {
513 Err($crate::StatusCode::BAD_TYPE)
514 }
515 }
516 }
517
518 #[doc = $native_doc]
519 #[repr(transparent)]
520 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
521
522 impl $native {
523 /// Create a new binder service.
524 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> impl $interface {
525 $crate::Binder::new($native(Box::new(inner)))
526 }
527 }
528
529 impl $crate::Remotable for $native {
530 fn get_descriptor() -> &'static str {
531 $descriptor
532 }
533
534 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
535 $on_transact(&*self.0, code, data, reply)
536 }
537
538 fn get_class() -> $crate::InterfaceClass {
539 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
540 static mut CLASS: Option<$crate::InterfaceClass> = None;
541
542 CLASS_INIT.call_once(|| unsafe {
543 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
544 // variable, and therefore is thread-safe, as it can only occur
545 // once.
546 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
547 });
548 unsafe {
549 // Safety: The `CLASS` variable can only be mutated once, above,
550 // and is subsequently safe to read from any thread.
551 CLASS.unwrap()
552 }
553 }
554 }
555
556 impl $crate::FromIBinder for dyn $interface {
557 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
558 use $crate::AssociateClass;
559 if !ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
560 return Err($crate::StatusCode::BAD_TYPE.into());
561 }
562
563 let service: $crate::Result<$crate::Binder<$native>> = std::convert::TryFrom::try_from(ibinder.clone());
564 if let Ok(service) = service {
565 Ok(Box::new(service))
566 } else {
567 Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))
568 }
569 }
570 }
571
572 impl $crate::parcel::Serialize for dyn $interface + '_
573 where
574 $interface: $crate::Interface
575 {
576 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
577 let binder = $crate::Interface::as_binder(self);
578 parcel.write(&binder)
579 }
580 }
581
582 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
583 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
584 parcel.write(&this.map($crate::Interface::as_binder))
585 }
586 }
587 };
588}