blob: 3899d47bd6e78091a81ee461905d56edca33f36e [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
59/// A local service that can be remotable via Binder.
60///
61/// An object that implement this interface made be made into a Binder service
62/// via `Binder::new(object)`.
63///
64/// This is a low-level interface that should normally be automatically
65/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
66/// the AIDL backend, users need only implement the high-level AIDL-defined
67/// interface. The AIDL compiler then generates a container struct that wraps
68/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -070069pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070070 /// The Binder interface descriptor string.
71 ///
72 /// This string is a unique identifier for a Binder interface, and should be
73 /// the same between all implementations of that interface.
74 fn get_descriptor() -> &'static str;
75
76 /// Handle and reply to a request to invoke a transaction on this object.
77 ///
78 /// `reply` may be [`None`] if the sender does not expect a reply.
79 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
80
81 /// Retrieve the class of this remote object.
82 ///
83 /// This method should always return the same InterfaceClass for the same
84 /// type.
85 fn get_class() -> InterfaceClass;
86}
87
Andrew Walbran12400d82021-03-04 17:04:34 +000088/// First transaction code available for user commands (inclusive)
89pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
90/// Last transaction code available for user commands (inclusive)
91pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
92
93/// Corresponds to TF_ONE_WAY -- an asynchronous call.
94pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
95/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
96pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
97
98/// Internal interface of binder local or remote objects for making
99/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700100///
Andrew Walbran12400d82021-03-04 17:04:34 +0000101/// This trait corresponds to the parts of the interface of the C++ `IBinder`
102/// class which are internal implementation details.
103pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700104 /// Is this object still alive?
105 fn is_binder_alive(&self) -> bool;
106
107 /// Send a ping transaction to this object
108 fn ping_binder(&mut self) -> Result<()>;
109
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700110 /// Indicate that the service intends to receive caller security contexts.
111 fn set_requesting_sid(&mut self, enable: bool);
112
Stephen Crane2a3c2502020-06-16 17:48:35 -0700113 /// Dump this object to the given file handle
114 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
115
116 /// Get a new interface that exposes additional extension functionality, if
117 /// available.
118 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
119
120 /// Perform a generic operation with the object.
121 ///
122 /// # Arguments
123 /// * `code` - Transaction code for the operation
124 /// * `data` - [`Parcel`] with input data
125 /// * `reply` - Optional [`Parcel`] for reply data
126 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000127 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700128 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
129 &self,
130 code: TransactionCode,
131 flags: TransactionFlags,
132 input_callback: F,
133 ) -> Result<Parcel>;
Andrew Walbran12400d82021-03-04 17:04:34 +0000134}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700135
Andrew Walbran12400d82021-03-04 17:04:34 +0000136/// Interface of binder local or remote objects.
137///
138/// This trait corresponds to the parts of the interface of the C++ `IBinder`
139/// class which are public.
140pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700141 /// Register the recipient for a notification if this binder
142 /// goes away. If this binder object unexpectedly goes away
143 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000144 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700145 ///
146 /// You will only receive death notifications for remote binders,
147 /// as local binders by definition can't die without you dying as well.
148 /// Trying to use this function on a local binder will result in an
149 /// INVALID_OPERATION code being returned and nothing happening.
150 ///
151 /// This link always holds a weak reference to its recipient.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700152 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
153
154 /// Remove a previously registered death notification.
155 /// The recipient will no longer be called if this object
156 /// dies.
157 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
158}
159
160/// Opaque reference to the type of a Binder interface.
161///
162/// This object encapsulates the Binder interface descriptor string, along with
163/// the binder transaction callback, if the class describes a local service.
164///
165/// A Binder remotable object may only have a single interface class, and any
166/// given object can only be associated with one class. Two objects with
167/// different classes are incompatible, even if both classes have the same
168/// interface descriptor.
169#[derive(Copy, Clone, PartialEq, Eq)]
170pub struct InterfaceClass(*const sys::AIBinder_Class);
171
172impl InterfaceClass {
173 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
174 ///
175 /// Note: the returned pointer will not be constant. Calling this method
176 /// multiple times for the same type will result in distinct class
177 /// pointers. A static getter for this value is implemented in
178 /// [`declare_binder_interface!`].
179 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
180 let descriptor = CString::new(I::get_descriptor()).unwrap();
181 let ptr = unsafe {
182 // Safety: `AIBinder_Class_define` expects a valid C string, and
183 // three valid callback functions, all non-null pointers. The C
184 // string is copied and need not be valid for longer than the call,
185 // so we can drop it after the call. We can safely assign null to
186 // the onDump and handleShellCommand callbacks as long as the class
187 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
188 // be a NULL pointer. Rust retains ownership of the pointer after it
189 // is defined.
190 let class = sys::AIBinder_Class_define(
191 descriptor.as_ptr(),
192 Some(I::on_create),
193 Some(I::on_destroy),
194 Some(I::on_transact),
195 );
196 if class.is_null() {
197 panic!("Expected non-null class pointer from AIBinder_Class_define!");
198 }
199 sys::AIBinder_Class_setOnDump(class, None);
200 sys::AIBinder_Class_setHandleShellCommand(class, None);
201 class
202 };
203 InterfaceClass(ptr)
204 }
205
206 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
207 /// pointer.
208 ///
209 /// # Safety
210 ///
211 /// This function is safe iff `ptr` is a valid, non-null pointer to an
212 /// `AIBinder_Class`.
213 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
214 InterfaceClass(ptr)
215 }
Stephen Crane669deb62020-09-10 17:31:39 -0700216
217 /// Get the interface descriptor string of this class.
218 pub fn get_descriptor(&self) -> String {
219 unsafe {
220 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
221 // is always a two-byte null terminated sequence of u16s. Thus, we
222 // can continue reading from the pointer until we hit a null value,
223 // and this pointer can be a valid slice if the slice length is <=
224 // the number of u16 elements before the null terminator.
225
226 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000227 CStr::from_ptr(raw_descriptor)
228 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700229 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
230 .into()
231 }
232 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700233}
234
235impl From<InterfaceClass> for *const sys::AIBinder_Class {
236 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
237 class.0
238 }
239}
240
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800241/// Strong reference to a binder object
242pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
243
244impl<I: FromIBinder + ?Sized> Strong<I> {
245 /// Create a new strong reference to the provided binder object
246 pub fn new(binder: Box<I>) -> Self {
247 Self(binder)
248 }
249
250 /// Construct a new weak reference to this binder
251 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
252 Weak::new(this)
253 }
254}
255
256impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
257 fn clone(&self) -> Self {
258 // Since we hold a strong reference, we should always be able to create
259 // a new strong reference to the same interface type, so try_from()
260 // should never fail here.
261 FromIBinder::try_from(self.0.as_binder()).unwrap()
262 }
263}
264
265impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
266 fn borrow(&self) -> &I {
267 &self.0
268 }
269}
270
271impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
272 fn as_ref(&self) -> &I {
273 &self.0
274 }
275}
276
277impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
278 type Target = I;
279
280 fn deref(&self) -> &Self::Target {
281 &self.0
282 }
283}
284
285impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
286 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
287 fmt::Debug::fmt(&**self, f)
288 }
289}
290
291impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
292 fn cmp(&self, other: &Self) -> Ordering {
293 self.0.as_binder().cmp(&other.0.as_binder())
294 }
295}
296
297impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
298 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
299 self.0.as_binder().partial_cmp(&other.0.as_binder())
300 }
301}
302
303impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
304 fn eq(&self, other: &Self) -> bool {
305 self.0.as_binder().eq(&other.0.as_binder())
306 }
307}
308
309impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
310
311/// Weak reference to a binder object
312#[derive(Debug)]
313pub struct Weak<I: FromIBinder + ?Sized> {
314 weak_binder: WpIBinder,
315 interface_type: PhantomData<I>,
316}
317
318impl<I: FromIBinder + ?Sized> Weak<I> {
319 /// Construct a new weak reference from a strong reference
320 fn new(binder: &Strong<I>) -> Self {
321 let weak_binder = binder.as_binder().downgrade();
322 Weak {
323 weak_binder,
324 interface_type: PhantomData,
325 }
326 }
327
328 /// Upgrade this weak reference to a strong reference if the binder object
329 /// is still alive
330 pub fn upgrade(&self) -> Result<Strong<I>> {
331 self.weak_binder
332 .promote()
333 .ok_or(StatusCode::DEAD_OBJECT)
334 .and_then(FromIBinder::try_from)
335 }
336}
337
338impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
339 fn clone(&self) -> Self {
340 Self {
341 weak_binder: self.weak_binder.clone(),
342 interface_type: PhantomData,
343 }
344 }
345}
346
347impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
348 fn cmp(&self, other: &Self) -> Ordering {
349 self.weak_binder.cmp(&other.weak_binder)
350 }
351}
352
353impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
354 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
355 self.weak_binder.partial_cmp(&other.weak_binder)
356 }
357}
358
359impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
360 fn eq(&self, other: &Self) -> bool {
361 self.weak_binder == other.weak_binder
362 }
363}
364
365impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
366
Stephen Crane2a3c2502020-06-16 17:48:35 -0700367/// Create a function implementing a static getter for an interface class.
368///
369/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
370/// [`Interface`]) must have global, static class that uniquely identifies
371/// it. This macro implements an [`InterfaceClass`] getter to simplify these
372/// implementations.
373///
374/// The type of a structure that implements [`InterfaceClassMethods`] must be
375/// passed to this macro. For local services, this should be `Binder<Self>`
376/// since [`Binder`] implements [`InterfaceClassMethods`].
377///
378/// # Examples
379///
380/// When implementing a local [`Remotable`] service `ExampleService`, the
381/// `get_class` method is required in the [`Remotable`] impl block. This macro
382/// should be used as follows to implement this functionality:
383///
384/// ```rust
385/// impl Remotable for ExampleService {
386/// fn get_descriptor() -> &'static str {
387/// "android.os.IExampleInterface"
388/// }
389///
390/// fn on_transact(
391/// &self,
392/// code: TransactionCode,
393/// data: &Parcel,
394/// reply: &mut Parcel,
395/// ) -> Result<()> {
396/// // ...
397/// }
398///
399/// binder_fn_get_class!(Binder<Self>);
400/// }
401/// ```
402macro_rules! binder_fn_get_class {
403 ($class:ty) => {
404 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
405 };
406
407 ($constructor:expr) => {
408 fn get_class() -> $crate::InterfaceClass {
409 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
410 static mut CLASS: Option<$crate::InterfaceClass> = None;
411
412 CLASS_INIT.call_once(|| unsafe {
413 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
414 // variable, and therefore is thread-safe, as it can only occur
415 // once.
416 CLASS = Some($constructor);
417 });
418 unsafe {
419 // Safety: The `CLASS` variable can only be mutated once, above,
420 // and is subsequently safe to read from any thread.
421 CLASS.unwrap()
422 }
423 }
424 };
425}
426
427pub trait InterfaceClassMethods {
428 /// Get the interface descriptor string for this object type.
429 fn get_descriptor() -> &'static str
430 where
431 Self: Sized;
432
433 /// Called during construction of a new `AIBinder` object of this interface
434 /// class.
435 ///
436 /// The opaque pointer parameter will be the parameter provided to
437 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
438 /// `AIBinder` object.
439 ///
440 /// # Safety
441 ///
442 /// Callback called from C++. The parameter argument provided to
443 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
444 /// will take ownership of the returned pointer, which it will free via
445 /// `on_destroy`.
446 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
447
448 /// Called when a transaction needs to be processed by the local service
449 /// implementation.
450 ///
451 /// # Safety
452 ///
453 /// Callback called from C++. The `binder` parameter must be a valid pointer
454 /// to a binder object of this class with userdata initialized via this
455 /// class's `on_create`. The parcel parameters must be valid pointers to
456 /// parcel objects.
457 unsafe extern "C" fn on_transact(
458 binder: *mut sys::AIBinder,
459 code: u32,
460 data: *const sys::AParcel,
461 reply: *mut sys::AParcel,
462 ) -> status_t;
463
464 /// Called whenever an `AIBinder` object is no longer referenced and needs
465 /// to be destroyed.
466 ///
467 /// # Safety
468 ///
469 /// Callback called from C++. The opaque pointer parameter must be the value
470 /// returned by `on_create` for this class. This function takes ownership of
471 /// the provided pointer and destroys it.
472 unsafe extern "C" fn on_destroy(object: *mut c_void);
473}
474
475/// Interface for transforming a generic SpIBinder into a specific remote
476/// interface trait.
477///
478/// # Example
479///
480/// For Binder interface `IFoo`, the following implementation should be made:
481/// ```no_run
482/// # use binder::{FromIBinder, SpIBinder, Result};
483/// # trait IFoo {}
484/// impl FromIBinder for dyn IFoo {
485/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
486/// // ...
487/// # Err(binder::StatusCode::OK)
488/// }
489/// }
490/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800491pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700492 /// Try to interpret a generic Binder object as this interface.
493 ///
494 /// Returns a trait object for the `Self` interface if this object
495 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800496 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700497}
498
499/// Trait for transparent Rust wrappers around android C++ native types.
500///
501/// The pointer return by this trait's methods should be immediately passed to
502/// C++ and not stored by Rust. The pointer is valid only as long as the
503/// underlying C++ object is alive, so users must be careful to take this into
504/// account, as Rust cannot enforce this.
505///
506/// # Safety
507///
508/// For this trait to be a correct implementation, `T` must be a valid android
509/// C++ type. Since we cannot constrain this via the type system, this trait is
510/// marked as unsafe.
511pub unsafe trait AsNative<T> {
512 /// Return a pointer to the native version of `self`
513 fn as_native(&self) -> *const T;
514
515 /// Return a mutable pointer to the native version of `self`
516 fn as_native_mut(&mut self) -> *mut T;
517}
518
519unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
520 fn as_native(&self) -> *const T {
521 self.as_ref().map_or(ptr::null(), |v| v.as_native())
522 }
523
524 fn as_native_mut(&mut self) -> *mut T {
525 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
526 }
527}
528
529/// Declare typed interfaces for a binder object.
530///
531/// Given an interface trait and descriptor string, create a native and remote
532/// proxy wrapper for this interface. The native service object (`$native`)
533/// implements `Remotable` and will dispatch to the function `$on_transact` to
534/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
535/// objects for this interface and can optionally contain additional fields.
536///
537/// Assuming the interface trait is `Interface`, `$on_transact` function must
538/// have the following type:
539///
540/// ```
541/// # use binder::{Interface, TransactionCode, Parcel};
542/// # trait Placeholder {
543/// fn on_transact(
544/// service: &dyn Interface,
545/// code: TransactionCode,
546/// data: &Parcel,
547/// reply: &mut Parcel,
548/// ) -> binder::Result<()>;
549/// # }
550/// ```
551///
552/// # Examples
553///
554/// The following example declares the local service type `BnServiceManager` and
555/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
556/// proxy respectively) for the `IServiceManager` Binder interface. The
557/// interfaces will be identified by the descriptor string
558/// "android.os.IServiceManager". The local service will dispatch transactions
559/// using the provided function, `on_transact`.
560///
561/// ```
562/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
563///
564/// pub trait IServiceManager: Interface {
565/// // remote methods...
566/// }
567///
568/// declare_binder_interface! {
569/// IServiceManager["android.os.IServiceManager"] {
570/// native: BnServiceManager(on_transact),
571/// proxy: BpServiceManager,
572/// }
573/// }
574///
575/// fn on_transact(
576/// service: &dyn IServiceManager,
577/// code: TransactionCode,
578/// data: &Parcel,
579/// reply: &mut Parcel,
580/// ) -> binder::Result<()> {
581/// // ...
582/// Ok(())
583/// }
584///
585/// impl IServiceManager for BpServiceManager {
586/// // parceling/unparceling code for the IServiceManager emitted here
587/// }
588///
589/// impl IServiceManager for Binder<BnServiceManager> {
590/// // Forward calls to local implementation
591/// }
592/// ```
593#[macro_export]
594macro_rules! declare_binder_interface {
595 {
596 $interface:path[$descriptor:expr] {
597 native: $native:ident($on_transact:path),
598 proxy: $proxy:ident,
599 }
600 } => {
601 $crate::declare_binder_interface! {
602 $interface[$descriptor] {
603 native: $native($on_transact),
604 proxy: $proxy {},
605 }
606 }
607 };
608
609 {
610 $interface:path[$descriptor:expr] {
611 native: $native:ident($on_transact:path),
612 proxy: $proxy:ident {
613 $($fname:ident: $fty:ty = $finit:expr),*
614 },
615 }
616 } => {
617 $crate::declare_binder_interface! {
618 $interface[$descriptor] {
619 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
620 native: $native($on_transact),
621 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
622 proxy: $proxy {
623 $($fname: $fty = $finit),*
624 },
625 }
626 }
627 };
628
629 {
630 $interface:path[$descriptor:expr] {
631 @doc[$native_doc:expr]
632 native: $native:ident($on_transact:path),
633
634 @doc[$proxy_doc:expr]
635 proxy: $proxy:ident {
636 $($fname:ident: $fty:ty = $finit:expr),*
637 },
638 }
639 } => {
640 #[doc = $proxy_doc]
641 pub struct $proxy {
642 binder: $crate::SpIBinder,
643 $($fname: $fty,)*
644 }
645
646 impl $crate::Interface for $proxy {
647 fn as_binder(&self) -> $crate::SpIBinder {
648 self.binder.clone()
649 }
650 }
651
652 impl $crate::Proxy for $proxy
653 where
654 $proxy: $interface,
655 {
656 fn get_descriptor() -> &'static str {
657 $descriptor
658 }
659
660 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700661 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700662 }
663 }
664
665 #[doc = $native_doc]
666 #[repr(transparent)]
667 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
668
669 impl $native {
670 /// Create a new binder service.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800671 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
672 let binder = $crate::Binder::new($native(Box::new(inner)));
673 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700674 }
675 }
676
677 impl $crate::Remotable for $native {
678 fn get_descriptor() -> &'static str {
679 $descriptor
680 }
681
682 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700683 match $on_transact(&*self.0, code, data, reply) {
684 // The C++ backend converts UNEXPECTED_NULL into an exception
685 Err($crate::StatusCode::UNEXPECTED_NULL) => {
686 let status = $crate::Status::new_exception(
687 $crate::ExceptionCode::NULL_POINTER,
688 None,
689 );
690 reply.write(&status)
691 },
692 result => result
693 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700694 }
695
696 fn get_class() -> $crate::InterfaceClass {
697 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
698 static mut CLASS: Option<$crate::InterfaceClass> = None;
699
700 CLASS_INIT.call_once(|| unsafe {
701 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
702 // variable, and therefore is thread-safe, as it can only occur
703 // once.
704 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
705 });
706 unsafe {
707 // Safety: The `CLASS` variable can only be mutated once, above,
708 // and is subsequently safe to read from any thread.
709 CLASS.unwrap()
710 }
711 }
712 }
713
714 impl $crate::FromIBinder for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800715 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700716 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700717
718 let existing_class = ibinder.get_class();
719 if let Some(class) = existing_class {
720 if class != <$native as $crate::Remotable>::get_class() &&
721 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
722 {
723 // The binder object's descriptor string matches what we
724 // expect. We still need to treat this local or already
725 // associated object as remote, because we can't cast it
726 // into a Rust service object without a matching class
727 // pointer.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800728 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700729 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700730 }
731
Stephen Crane669deb62020-09-10 17:31:39 -0700732 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
733 let service: $crate::Result<$crate::Binder<$native>> =
734 std::convert::TryFrom::try_from(ibinder.clone());
735 if let Ok(service) = service {
736 // We were able to associate with our expected class and
737 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800738 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700739 } else {
740 // Service is remote
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800741 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700742 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000743 }
Stephen Crane669deb62020-09-10 17:31:39 -0700744
745 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700746 }
747 }
748
749 impl $crate::parcel::Serialize for dyn $interface + '_
750 where
Stephen Craned58bce02020-07-07 12:26:02 -0700751 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700752 {
753 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
754 let binder = $crate::Interface::as_binder(self);
755 parcel.write(&binder)
756 }
757 }
758
759 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
760 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
761 parcel.write(&this.map($crate::Interface::as_binder))
762 }
763 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700764
765 impl std::fmt::Debug for dyn $interface {
766 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
767 f.pad(stringify!($interface))
768 }
769 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700770
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800771 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700772 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800773 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700774 fn to_owned(&self) -> Self::Owned {
775 self.as_binder().into_interface()
776 .expect(concat!("Error cloning interface ", stringify!($interface)))
777 }
778 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700779 };
780}
Andrei Homescu00eca712020-09-09 18:57:40 -0700781
782/// Declare an AIDL enumeration.
783///
784/// This is mainly used internally by the AIDL compiler.
785#[macro_export]
786macro_rules! declare_binder_enum {
787 {
788 $enum:ident : $backing:ty {
789 $( $name:ident = $value:expr, )*
790 }
791 } => {
792 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
793 pub struct $enum(pub $backing);
794 impl $enum {
795 $( pub const $name: Self = Self($value); )*
796 }
797
798 impl $crate::parcel::Serialize for $enum {
799 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
800 parcel.write(&self.0)
801 }
802 }
803
804 impl $crate::parcel::SerializeArray for $enum {
805 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
806 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
807 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
808 }
809 }
810
811 impl $crate::parcel::Deserialize for $enum {
812 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
813 parcel.read().map(Self)
814 }
815 }
816
817 impl $crate::parcel::DeserializeArray for $enum {
818 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
819 let v: Option<Vec<$backing>> =
820 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
821 Ok(v.map(|v| v.into_iter().map(Self).collect()))
822 }
823 }
824 };
825}