blob: 695a83e414ba6a274db10c7c4f5b04d2aa227349 [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
Stephen Craneddb3e6d2020-12-18 13:27:22 -080019use crate::error::{status_t, Result, StatusCode};
Stephen Crane2a3c2502020-06-16 17:48:35 -070020use crate::parcel::Parcel;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080021use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
Stephen Crane2a3c2502020-06-16 17:48:35 -070022use crate::sys;
23
Stephen Craneddb3e6d2020-12-18 13:27:22 -080024use std::borrow::Borrow;
25use std::cmp::Ordering;
Stephen Crane669deb62020-09-10 17:31:39 -070026use std::ffi::{c_void, CStr, CString};
Stephen Craneddb3e6d2020-12-18 13:27:22 -080027use std::fmt;
28use std::marker::PhantomData;
29use std::ops::Deref;
Stephen Crane669deb62020-09-10 17:31:39 -070030use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070031use std::os::unix::io::AsRawFd;
32use std::ptr;
33
34/// Binder action to perform.
35///
Andrew Walbran12400d82021-03-04 17:04:34 +000036/// This must be a number between [`FIRST_CALL_TRANSACTION`] and
37/// [`LAST_CALL_TRANSACTION`].
Stephen Crane2a3c2502020-06-16 17:48:35 -070038pub type TransactionCode = u32;
39
40/// Additional operation flags.
41///
Andrew Walbran12400d82021-03-04 17:04:34 +000042/// `FLAG_*` values.
Stephen Crane2a3c2502020-06-16 17:48:35 -070043pub type TransactionFlags = u32;
44
45/// Super-trait for Binder interfaces.
46///
47/// This trait allows conversion of a Binder interface trait object into an
48/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
49/// interfaces) must implement this trait.
50///
51/// This is equivalent `IInterface` in C++.
Stephen Craneddb3e6d2020-12-18 13:27:22 -080052pub trait Interface: Send {
Stephen Crane2a3c2502020-06-16 17:48:35 -070053 /// Convert this binder object into a generic [`SpIBinder`] reference.
54 fn as_binder(&self) -> SpIBinder {
55 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
56 }
57}
58
Stephen Craneff7f03a2021-02-25 16:04:22 -080059/// Interface stability promise
60///
61/// An interface can promise to be a stable vendor interface ([`Vintf`]), or
62/// makes no stability guarantees ([`Local`]). [`Local`] is
63/// currently the default stability.
64pub enum Stability {
65 /// Default stability, visible to other modules in the same compilation
66 /// context (e.g. modules on system.img)
67 Local,
68
69 /// A Vendor Interface Object, which promises to be stable
70 Vintf,
71}
72
73impl Default for Stability {
74 fn default() -> Self {
75 Stability::Local
76 }
77}
78
Stephen Crane2a3c2502020-06-16 17:48:35 -070079/// A local service that can be remotable via Binder.
80///
81/// An object that implement this interface made be made into a Binder service
82/// via `Binder::new(object)`.
83///
84/// This is a low-level interface that should normally be automatically
85/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
86/// the AIDL backend, users need only implement the high-level AIDL-defined
87/// interface. The AIDL compiler then generates a container struct that wraps
88/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -070089pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070090 /// The Binder interface descriptor string.
91 ///
92 /// This string is a unique identifier for a Binder interface, and should be
93 /// the same between all implementations of that interface.
94 fn get_descriptor() -> &'static str;
95
96 /// Handle and reply to a request to invoke a transaction on this object.
97 ///
98 /// `reply` may be [`None`] if the sender does not expect a reply.
99 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
100
101 /// Retrieve the class of this remote object.
102 ///
103 /// This method should always return the same InterfaceClass for the same
104 /// type.
105 fn get_class() -> InterfaceClass;
106}
107
Andrew Walbran12400d82021-03-04 17:04:34 +0000108/// First transaction code available for user commands (inclusive)
109pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
110/// Last transaction code available for user commands (inclusive)
111pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
112
113/// Corresponds to TF_ONE_WAY -- an asynchronous call.
114pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
115/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
116pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800117/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
118pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000119
120/// Internal interface of binder local or remote objects for making
121/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700122///
Andrew Walbran12400d82021-03-04 17:04:34 +0000123/// This trait corresponds to the parts of the interface of the C++ `IBinder`
124/// class which are internal implementation details.
125pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700126 /// Is this object still alive?
127 fn is_binder_alive(&self) -> bool;
128
129 /// Send a ping transaction to this object
130 fn ping_binder(&mut self) -> Result<()>;
131
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700132 /// Indicate that the service intends to receive caller security contexts.
133 fn set_requesting_sid(&mut self, enable: bool);
134
Stephen Crane2a3c2502020-06-16 17:48:35 -0700135 /// Dump this object to the given file handle
136 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
137
138 /// Get a new interface that exposes additional extension functionality, if
139 /// available.
140 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
141
142 /// Perform a generic operation with the object.
143 ///
144 /// # Arguments
145 /// * `code` - Transaction code for the operation
146 /// * `data` - [`Parcel`] with input data
147 /// * `reply` - Optional [`Parcel`] for reply data
148 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000149 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700150 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
151 &self,
152 code: TransactionCode,
153 flags: TransactionFlags,
154 input_callback: F,
155 ) -> Result<Parcel>;
Andrew Walbran12400d82021-03-04 17:04:34 +0000156}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700157
Andrew Walbran12400d82021-03-04 17:04:34 +0000158/// Interface of binder local or remote objects.
159///
160/// This trait corresponds to the parts of the interface of the C++ `IBinder`
161/// class which are public.
162pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700163 /// Register the recipient for a notification if this binder
164 /// goes away. If this binder object unexpectedly goes away
165 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000166 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700167 ///
168 /// You will only receive death notifications for remote binders,
169 /// as local binders by definition can't die without you dying as well.
170 /// Trying to use this function on a local binder will result in an
171 /// INVALID_OPERATION code being returned and nothing happening.
172 ///
173 /// This link always holds a weak reference to its recipient.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700174 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
175
176 /// Remove a previously registered death notification.
177 /// The recipient will no longer be called if this object
178 /// dies.
179 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
180}
181
182/// Opaque reference to the type of a Binder interface.
183///
184/// This object encapsulates the Binder interface descriptor string, along with
185/// the binder transaction callback, if the class describes a local service.
186///
187/// A Binder remotable object may only have a single interface class, and any
188/// given object can only be associated with one class. Two objects with
189/// different classes are incompatible, even if both classes have the same
190/// interface descriptor.
191#[derive(Copy, Clone, PartialEq, Eq)]
192pub struct InterfaceClass(*const sys::AIBinder_Class);
193
194impl InterfaceClass {
195 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
196 ///
197 /// Note: the returned pointer will not be constant. Calling this method
198 /// multiple times for the same type will result in distinct class
199 /// pointers. A static getter for this value is implemented in
200 /// [`declare_binder_interface!`].
201 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
202 let descriptor = CString::new(I::get_descriptor()).unwrap();
203 let ptr = unsafe {
204 // Safety: `AIBinder_Class_define` expects a valid C string, and
205 // three valid callback functions, all non-null pointers. The C
206 // string is copied and need not be valid for longer than the call,
207 // so we can drop it after the call. We can safely assign null to
208 // the onDump and handleShellCommand callbacks as long as the class
209 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
210 // be a NULL pointer. Rust retains ownership of the pointer after it
211 // is defined.
212 let class = sys::AIBinder_Class_define(
213 descriptor.as_ptr(),
214 Some(I::on_create),
215 Some(I::on_destroy),
216 Some(I::on_transact),
217 );
218 if class.is_null() {
219 panic!("Expected non-null class pointer from AIBinder_Class_define!");
220 }
221 sys::AIBinder_Class_setOnDump(class, None);
222 sys::AIBinder_Class_setHandleShellCommand(class, None);
223 class
224 };
225 InterfaceClass(ptr)
226 }
227
228 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
229 /// pointer.
230 ///
231 /// # Safety
232 ///
233 /// This function is safe iff `ptr` is a valid, non-null pointer to an
234 /// `AIBinder_Class`.
235 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
236 InterfaceClass(ptr)
237 }
Stephen Crane669deb62020-09-10 17:31:39 -0700238
239 /// Get the interface descriptor string of this class.
240 pub fn get_descriptor(&self) -> String {
241 unsafe {
242 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
243 // is always a two-byte null terminated sequence of u16s. Thus, we
244 // can continue reading from the pointer until we hit a null value,
245 // and this pointer can be a valid slice if the slice length is <=
246 // the number of u16 elements before the null terminator.
247
248 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000249 CStr::from_ptr(raw_descriptor)
250 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700251 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
252 .into()
253 }
254 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700255}
256
257impl From<InterfaceClass> for *const sys::AIBinder_Class {
258 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
259 class.0
260 }
261}
262
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800263/// Strong reference to a binder object
264pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
265
266impl<I: FromIBinder + ?Sized> Strong<I> {
267 /// Create a new strong reference to the provided binder object
268 pub fn new(binder: Box<I>) -> Self {
269 Self(binder)
270 }
271
272 /// Construct a new weak reference to this binder
273 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
274 Weak::new(this)
275 }
276}
277
278impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
279 fn clone(&self) -> Self {
280 // Since we hold a strong reference, we should always be able to create
281 // a new strong reference to the same interface type, so try_from()
282 // should never fail here.
283 FromIBinder::try_from(self.0.as_binder()).unwrap()
284 }
285}
286
287impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
288 fn borrow(&self) -> &I {
289 &self.0
290 }
291}
292
293impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
294 fn as_ref(&self) -> &I {
295 &self.0
296 }
297}
298
299impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
300 type Target = I;
301
302 fn deref(&self) -> &Self::Target {
303 &self.0
304 }
305}
306
307impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
308 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
309 fmt::Debug::fmt(&**self, f)
310 }
311}
312
313impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
314 fn cmp(&self, other: &Self) -> Ordering {
315 self.0.as_binder().cmp(&other.0.as_binder())
316 }
317}
318
319impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
320 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
321 self.0.as_binder().partial_cmp(&other.0.as_binder())
322 }
323}
324
325impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
326 fn eq(&self, other: &Self) -> bool {
327 self.0.as_binder().eq(&other.0.as_binder())
328 }
329}
330
331impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
332
333/// Weak reference to a binder object
334#[derive(Debug)]
335pub struct Weak<I: FromIBinder + ?Sized> {
336 weak_binder: WpIBinder,
337 interface_type: PhantomData<I>,
338}
339
340impl<I: FromIBinder + ?Sized> Weak<I> {
341 /// Construct a new weak reference from a strong reference
342 fn new(binder: &Strong<I>) -> Self {
343 let weak_binder = binder.as_binder().downgrade();
344 Weak {
345 weak_binder,
346 interface_type: PhantomData,
347 }
348 }
349
350 /// Upgrade this weak reference to a strong reference if the binder object
351 /// is still alive
352 pub fn upgrade(&self) -> Result<Strong<I>> {
353 self.weak_binder
354 .promote()
355 .ok_or(StatusCode::DEAD_OBJECT)
356 .and_then(FromIBinder::try_from)
357 }
358}
359
360impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
361 fn clone(&self) -> Self {
362 Self {
363 weak_binder: self.weak_binder.clone(),
364 interface_type: PhantomData,
365 }
366 }
367}
368
369impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
370 fn cmp(&self, other: &Self) -> Ordering {
371 self.weak_binder.cmp(&other.weak_binder)
372 }
373}
374
375impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
376 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
377 self.weak_binder.partial_cmp(&other.weak_binder)
378 }
379}
380
381impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
382 fn eq(&self, other: &Self) -> bool {
383 self.weak_binder == other.weak_binder
384 }
385}
386
387impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
388
Stephen Crane2a3c2502020-06-16 17:48:35 -0700389/// Create a function implementing a static getter for an interface class.
390///
391/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
392/// [`Interface`]) must have global, static class that uniquely identifies
393/// it. This macro implements an [`InterfaceClass`] getter to simplify these
394/// implementations.
395///
396/// The type of a structure that implements [`InterfaceClassMethods`] must be
397/// passed to this macro. For local services, this should be `Binder<Self>`
398/// since [`Binder`] implements [`InterfaceClassMethods`].
399///
400/// # Examples
401///
402/// When implementing a local [`Remotable`] service `ExampleService`, the
403/// `get_class` method is required in the [`Remotable`] impl block. This macro
404/// should be used as follows to implement this functionality:
405///
406/// ```rust
407/// impl Remotable for ExampleService {
408/// fn get_descriptor() -> &'static str {
409/// "android.os.IExampleInterface"
410/// }
411///
412/// fn on_transact(
413/// &self,
414/// code: TransactionCode,
415/// data: &Parcel,
416/// reply: &mut Parcel,
417/// ) -> Result<()> {
418/// // ...
419/// }
420///
421/// binder_fn_get_class!(Binder<Self>);
422/// }
423/// ```
424macro_rules! binder_fn_get_class {
425 ($class:ty) => {
426 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
427 };
428
429 ($constructor:expr) => {
430 fn get_class() -> $crate::InterfaceClass {
431 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
432 static mut CLASS: Option<$crate::InterfaceClass> = None;
433
434 CLASS_INIT.call_once(|| unsafe {
435 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
436 // variable, and therefore is thread-safe, as it can only occur
437 // once.
438 CLASS = Some($constructor);
439 });
440 unsafe {
441 // Safety: The `CLASS` variable can only be mutated once, above,
442 // and is subsequently safe to read from any thread.
443 CLASS.unwrap()
444 }
445 }
446 };
447}
448
449pub trait InterfaceClassMethods {
450 /// Get the interface descriptor string for this object type.
451 fn get_descriptor() -> &'static str
452 where
453 Self: Sized;
454
455 /// Called during construction of a new `AIBinder` object of this interface
456 /// class.
457 ///
458 /// The opaque pointer parameter will be the parameter provided to
459 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
460 /// `AIBinder` object.
461 ///
462 /// # Safety
463 ///
464 /// Callback called from C++. The parameter argument provided to
465 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
466 /// will take ownership of the returned pointer, which it will free via
467 /// `on_destroy`.
468 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
469
470 /// Called when a transaction needs to be processed by the local service
471 /// implementation.
472 ///
473 /// # Safety
474 ///
475 /// Callback called from C++. The `binder` parameter must be a valid pointer
476 /// to a binder object of this class with userdata initialized via this
477 /// class's `on_create`. The parcel parameters must be valid pointers to
478 /// parcel objects.
479 unsafe extern "C" fn on_transact(
480 binder: *mut sys::AIBinder,
481 code: u32,
482 data: *const sys::AParcel,
483 reply: *mut sys::AParcel,
484 ) -> status_t;
485
486 /// Called whenever an `AIBinder` object is no longer referenced and needs
487 /// to be destroyed.
488 ///
489 /// # Safety
490 ///
491 /// Callback called from C++. The opaque pointer parameter must be the value
492 /// returned by `on_create` for this class. This function takes ownership of
493 /// the provided pointer and destroys it.
494 unsafe extern "C" fn on_destroy(object: *mut c_void);
495}
496
497/// Interface for transforming a generic SpIBinder into a specific remote
498/// interface trait.
499///
500/// # Example
501///
502/// For Binder interface `IFoo`, the following implementation should be made:
503/// ```no_run
504/// # use binder::{FromIBinder, SpIBinder, Result};
505/// # trait IFoo {}
506/// impl FromIBinder for dyn IFoo {
507/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
508/// // ...
509/// # Err(binder::StatusCode::OK)
510/// }
511/// }
512/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800513pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700514 /// Try to interpret a generic Binder object as this interface.
515 ///
516 /// Returns a trait object for the `Self` interface if this object
517 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800518 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700519}
520
521/// Trait for transparent Rust wrappers around android C++ native types.
522///
523/// The pointer return by this trait's methods should be immediately passed to
524/// C++ and not stored by Rust. The pointer is valid only as long as the
525/// underlying C++ object is alive, so users must be careful to take this into
526/// account, as Rust cannot enforce this.
527///
528/// # Safety
529///
530/// For this trait to be a correct implementation, `T` must be a valid android
531/// C++ type. Since we cannot constrain this via the type system, this trait is
532/// marked as unsafe.
533pub unsafe trait AsNative<T> {
534 /// Return a pointer to the native version of `self`
535 fn as_native(&self) -> *const T;
536
537 /// Return a mutable pointer to the native version of `self`
538 fn as_native_mut(&mut self) -> *mut T;
539}
540
541unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
542 fn as_native(&self) -> *const T {
543 self.as_ref().map_or(ptr::null(), |v| v.as_native())
544 }
545
546 fn as_native_mut(&mut self) -> *mut T {
547 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
548 }
549}
550
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000551/// The features to enable when creating a native Binder.
552///
553/// This should always be initialised with a default value, e.g.:
554/// ```
555/// # use binder::BinderFeatures;
556/// BinderFeatures {
557/// set_requesting_sid: true,
558/// ..BinderFeatures::default(),
559/// }
560/// ```
561#[derive(Clone, Debug, Default, Eq, PartialEq)]
562pub struct BinderFeatures {
563 /// Indicates that the service intends to receive caller security contexts. This must be true
564 /// for `ThreadState::with_calling_sid` to work.
565 pub set_requesting_sid: bool,
566 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
567 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
568 // expressions entirely.
569 #[doc(hidden)]
570 pub _non_exhaustive: (),
571}
572
Stephen Crane2a3c2502020-06-16 17:48:35 -0700573/// Declare typed interfaces for a binder object.
574///
575/// Given an interface trait and descriptor string, create a native and remote
576/// proxy wrapper for this interface. The native service object (`$native`)
577/// implements `Remotable` and will dispatch to the function `$on_transact` to
578/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
579/// objects for this interface and can optionally contain additional fields.
580///
581/// Assuming the interface trait is `Interface`, `$on_transact` function must
582/// have the following type:
583///
584/// ```
585/// # use binder::{Interface, TransactionCode, Parcel};
586/// # trait Placeholder {
587/// fn on_transact(
588/// service: &dyn Interface,
589/// code: TransactionCode,
590/// data: &Parcel,
591/// reply: &mut Parcel,
592/// ) -> binder::Result<()>;
593/// # }
594/// ```
595///
596/// # Examples
597///
598/// The following example declares the local service type `BnServiceManager` and
599/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
600/// proxy respectively) for the `IServiceManager` Binder interface. The
601/// interfaces will be identified by the descriptor string
602/// "android.os.IServiceManager". The local service will dispatch transactions
603/// using the provided function, `on_transact`.
604///
605/// ```
606/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
607///
608/// pub trait IServiceManager: Interface {
609/// // remote methods...
610/// }
611///
612/// declare_binder_interface! {
613/// IServiceManager["android.os.IServiceManager"] {
614/// native: BnServiceManager(on_transact),
615/// proxy: BpServiceManager,
616/// }
617/// }
618///
619/// fn on_transact(
620/// service: &dyn IServiceManager,
621/// code: TransactionCode,
622/// data: &Parcel,
623/// reply: &mut Parcel,
624/// ) -> binder::Result<()> {
625/// // ...
626/// Ok(())
627/// }
628///
629/// impl IServiceManager for BpServiceManager {
630/// // parceling/unparceling code for the IServiceManager emitted here
631/// }
632///
633/// impl IServiceManager for Binder<BnServiceManager> {
634/// // Forward calls to local implementation
635/// }
636/// ```
637#[macro_export]
638macro_rules! declare_binder_interface {
639 {
640 $interface:path[$descriptor:expr] {
641 native: $native:ident($on_transact:path),
642 proxy: $proxy:ident,
643 }
644 } => {
645 $crate::declare_binder_interface! {
646 $interface[$descriptor] {
647 native: $native($on_transact),
648 proxy: $proxy {},
Stephen Craneff7f03a2021-02-25 16:04:22 -0800649 stability: $crate::Stability::default(),
650 }
651 }
652 };
653
654 {
655 $interface:path[$descriptor:expr] {
656 native: $native:ident($on_transact:path),
657 proxy: $proxy:ident,
658 stability: $stability:expr,
659 }
660 } => {
661 $crate::declare_binder_interface! {
662 $interface[$descriptor] {
663 native: $native($on_transact),
664 proxy: $proxy {},
665 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700666 }
667 }
668 };
669
670 {
671 $interface:path[$descriptor:expr] {
672 native: $native:ident($on_transact:path),
673 proxy: $proxy:ident {
674 $($fname:ident: $fty:ty = $finit:expr),*
675 },
676 }
677 } => {
678 $crate::declare_binder_interface! {
679 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800680 native: $native($on_transact),
681 proxy: $proxy {
682 $($fname: $fty = $finit),*
683 },
684 stability: $crate::Stability::default(),
685 }
686 }
687 };
688
689 {
690 $interface:path[$descriptor:expr] {
691 native: $native:ident($on_transact:path),
692 proxy: $proxy:ident {
693 $($fname:ident: $fty:ty = $finit:expr),*
694 },
695 stability: $stability:expr,
696 }
697 } => {
698 $crate::declare_binder_interface! {
699 $interface[$descriptor] {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700700 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
701 native: $native($on_transact),
702 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
703 proxy: $proxy {
704 $($fname: $fty = $finit),*
705 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800706 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700707 }
708 }
709 };
710
711 {
712 $interface:path[$descriptor:expr] {
713 @doc[$native_doc:expr]
714 native: $native:ident($on_transact:path),
715
716 @doc[$proxy_doc:expr]
717 proxy: $proxy:ident {
718 $($fname:ident: $fty:ty = $finit:expr),*
719 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800720
721 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700722 }
723 } => {
724 #[doc = $proxy_doc]
725 pub struct $proxy {
726 binder: $crate::SpIBinder,
727 $($fname: $fty,)*
728 }
729
730 impl $crate::Interface for $proxy {
731 fn as_binder(&self) -> $crate::SpIBinder {
732 self.binder.clone()
733 }
734 }
735
736 impl $crate::Proxy for $proxy
737 where
738 $proxy: $interface,
739 {
740 fn get_descriptor() -> &'static str {
741 $descriptor
742 }
743
744 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700745 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700746 }
747 }
748
749 #[doc = $native_doc]
750 #[repr(transparent)]
751 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
752
753 impl $native {
754 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000755 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
756 let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
757 $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800758 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700759 }
760 }
761
762 impl $crate::Remotable for $native {
763 fn get_descriptor() -> &'static str {
764 $descriptor
765 }
766
767 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700768 match $on_transact(&*self.0, code, data, reply) {
769 // The C++ backend converts UNEXPECTED_NULL into an exception
770 Err($crate::StatusCode::UNEXPECTED_NULL) => {
771 let status = $crate::Status::new_exception(
772 $crate::ExceptionCode::NULL_POINTER,
773 None,
774 );
775 reply.write(&status)
776 },
777 result => result
778 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700779 }
780
781 fn get_class() -> $crate::InterfaceClass {
782 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
783 static mut CLASS: Option<$crate::InterfaceClass> = None;
784
785 CLASS_INIT.call_once(|| unsafe {
786 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
787 // variable, and therefore is thread-safe, as it can only occur
788 // once.
789 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
790 });
791 unsafe {
792 // Safety: The `CLASS` variable can only be mutated once, above,
793 // and is subsequently safe to read from any thread.
794 CLASS.unwrap()
795 }
796 }
797 }
798
799 impl $crate::FromIBinder for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800800 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700801 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700802
803 let existing_class = ibinder.get_class();
804 if let Some(class) = existing_class {
805 if class != <$native as $crate::Remotable>::get_class() &&
806 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
807 {
808 // The binder object's descriptor string matches what we
809 // expect. We still need to treat this local or already
810 // associated object as remote, because we can't cast it
811 // into a Rust service object without a matching class
812 // pointer.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800813 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700814 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700815 }
816
Stephen Crane669deb62020-09-10 17:31:39 -0700817 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
818 let service: $crate::Result<$crate::Binder<$native>> =
819 std::convert::TryFrom::try_from(ibinder.clone());
820 if let Ok(service) = service {
821 // We were able to associate with our expected class and
822 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800823 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700824 } else {
825 // Service is remote
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800826 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700827 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000828 }
Stephen Crane669deb62020-09-10 17:31:39 -0700829
830 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700831 }
832 }
833
834 impl $crate::parcel::Serialize for dyn $interface + '_
835 where
Stephen Craned58bce02020-07-07 12:26:02 -0700836 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700837 {
838 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
839 let binder = $crate::Interface::as_binder(self);
840 parcel.write(&binder)
841 }
842 }
843
844 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
845 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
846 parcel.write(&this.map($crate::Interface::as_binder))
847 }
848 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700849
850 impl std::fmt::Debug for dyn $interface {
851 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
852 f.pad(stringify!($interface))
853 }
854 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700855
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800856 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700857 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800858 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700859 fn to_owned(&self) -> Self::Owned {
860 self.as_binder().into_interface()
861 .expect(concat!("Error cloning interface ", stringify!($interface)))
862 }
863 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700864 };
865}
Andrei Homescu00eca712020-09-09 18:57:40 -0700866
867/// Declare an AIDL enumeration.
868///
869/// This is mainly used internally by the AIDL compiler.
870#[macro_export]
871macro_rules! declare_binder_enum {
872 {
873 $enum:ident : $backing:ty {
874 $( $name:ident = $value:expr, )*
875 }
876 } => {
877 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
878 pub struct $enum(pub $backing);
879 impl $enum {
880 $( pub const $name: Self = Self($value); )*
881 }
882
883 impl $crate::parcel::Serialize for $enum {
884 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
885 parcel.write(&self.0)
886 }
887 }
888
889 impl $crate::parcel::SerializeArray for $enum {
890 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
891 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
892 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
893 }
894 }
895
896 impl $crate::parcel::Deserialize for $enum {
897 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
898 parcel.read().map(Self)
899 }
900 }
901
902 impl $crate::parcel::DeserializeArray for $enum {
903 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
904 let v: Option<Vec<$backing>> =
905 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
906 Ok(v.map(|v| v.into_iter().map(Self).collect()))
907 }
908 }
909 };
910}