blob: 4d6b294000dfbaefd2024f33d594460465976949 [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};
Alice Ryhl8618c482021-11-09 15:35:35 +000020use crate::parcel::{Parcel, BorrowedParcel};
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;
Andrei Homescuee132fa2021-09-03 02:36:17 +000026use std::convert::TryFrom;
Stephen Crane669deb62020-09-10 17:31:39 -070027use std::ffi::{c_void, CStr, CString};
Stephen Craneddb3e6d2020-12-18 13:27:22 -080028use std::fmt;
Stephen Crane2a3297f2021-06-11 16:48:10 -070029use std::fs::File;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080030use std::marker::PhantomData;
31use std::ops::Deref;
Stephen Crane669deb62020-09-10 17:31:39 -070032use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070033use std::os::unix::io::AsRawFd;
34use std::ptr;
35
36/// Binder action to perform.
37///
Andrew Walbran12400d82021-03-04 17:04:34 +000038/// This must be a number between [`FIRST_CALL_TRANSACTION`] and
39/// [`LAST_CALL_TRANSACTION`].
Stephen Crane2a3c2502020-06-16 17:48:35 -070040pub type TransactionCode = u32;
41
42/// Additional operation flags.
43///
Andrew Walbran12400d82021-03-04 17:04:34 +000044/// `FLAG_*` values.
Stephen Crane2a3c2502020-06-16 17:48:35 -070045pub type TransactionFlags = u32;
46
47/// Super-trait for Binder interfaces.
48///
49/// This trait allows conversion of a Binder interface trait object into an
50/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
51/// interfaces) must implement this trait.
52///
53/// This is equivalent `IInterface` in C++.
Stephen Cranef03fe3d2021-06-25 15:05:00 -070054pub trait Interface: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070055 /// Convert this binder object into a generic [`SpIBinder`] reference.
56 fn as_binder(&self) -> SpIBinder {
57 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
58 }
Stephen Crane2a3297f2021-06-11 16:48:10 -070059
60 /// Dump transaction handler for this Binder object.
61 ///
62 /// This handler is a no-op by default and should be implemented for each
63 /// Binder service struct that wishes to respond to dump transactions.
64 fn dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
65 Ok(())
66 }
Stephen Crane2a3c2502020-06-16 17:48:35 -070067}
68
Alice Ryhlc1736842021-11-23 12:38:51 +000069/// Implemented by sync interfaces to specify what the associated async interface is.
70/// Generic to handle the fact that async interfaces are generic over a thread pool.
71///
72/// The binder in any object implementing this trait should be compatible with the
73/// `Target` associated type, and using `FromIBinder` to convert it to the target
74/// should not fail.
75pub trait ToAsyncInterface<P>
76where
77 Self: Interface,
78 Self::Target: FromIBinder,
79{
80 /// The async interface associated with this sync interface.
81 type Target: ?Sized;
82}
83
84/// Implemented by async interfaces to specify what the associated sync interface is.
85///
86/// The binder in any object implementing this trait should be compatible with the
87/// `Target` associated type, and using `FromIBinder` to convert it to the target
88/// should not fail.
89pub trait ToSyncInterface
90where
91 Self: Interface,
92 Self::Target: FromIBinder,
93{
94 /// The sync interface associated with this async interface.
95 type Target: ?Sized;
96}
97
Stephen Craneff7f03a2021-02-25 16:04:22 -080098/// Interface stability promise
99///
100/// An interface can promise to be a stable vendor interface ([`Vintf`]), or
101/// makes no stability guarantees ([`Local`]). [`Local`] is
102/// currently the default stability.
Andrei Homescuee132fa2021-09-03 02:36:17 +0000103#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800104pub enum Stability {
105 /// Default stability, visible to other modules in the same compilation
106 /// context (e.g. modules on system.img)
107 Local,
108
109 /// A Vendor Interface Object, which promises to be stable
110 Vintf,
111}
112
113impl Default for Stability {
114 fn default() -> Self {
115 Stability::Local
116 }
117}
118
Andrei Homescuee132fa2021-09-03 02:36:17 +0000119impl From<Stability> for i32 {
120 fn from(stability: Stability) -> i32 {
121 use Stability::*;
122 match stability {
123 Local => 0,
124 Vintf => 1,
125 }
126 }
127}
128
129impl TryFrom<i32> for Stability {
130 type Error = StatusCode;
131 fn try_from(stability: i32) -> Result<Stability> {
132 use Stability::*;
133 match stability {
134 0 => Ok(Local),
135 1 => Ok(Vintf),
136 _ => Err(StatusCode::BAD_VALUE)
137 }
138 }
139}
140
Stephen Crane2a3c2502020-06-16 17:48:35 -0700141/// A local service that can be remotable via Binder.
142///
143/// An object that implement this interface made be made into a Binder service
144/// via `Binder::new(object)`.
145///
146/// This is a low-level interface that should normally be automatically
147/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
148/// the AIDL backend, users need only implement the high-level AIDL-defined
149/// interface. The AIDL compiler then generates a container struct that wraps
150/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -0700151pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700152 /// The Binder interface descriptor string.
153 ///
154 /// This string is a unique identifier for a Binder interface, and should be
155 /// the same between all implementations of that interface.
156 fn get_descriptor() -> &'static str;
157
158 /// Handle and reply to a request to invoke a transaction on this object.
159 ///
160 /// `reply` may be [`None`] if the sender does not expect a reply.
Alice Ryhl8618c482021-11-09 15:35:35 +0000161 fn on_transact(&self, code: TransactionCode, data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700162
Stephen Crane2a3297f2021-06-11 16:48:10 -0700163 /// Handle a request to invoke the dump transaction on this
164 /// object.
165 fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>;
166
Stephen Crane2a3c2502020-06-16 17:48:35 -0700167 /// Retrieve the class of this remote object.
168 ///
169 /// This method should always return the same InterfaceClass for the same
170 /// type.
171 fn get_class() -> InterfaceClass;
172}
173
Andrew Walbran12400d82021-03-04 17:04:34 +0000174/// First transaction code available for user commands (inclusive)
175pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
176/// Last transaction code available for user commands (inclusive)
177pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
178
179/// Corresponds to TF_ONE_WAY -- an asynchronous call.
180pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
181/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
182pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800183/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
184pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000185
186/// Internal interface of binder local or remote objects for making
187/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700188///
Andrew Walbran12400d82021-03-04 17:04:34 +0000189/// This trait corresponds to the parts of the interface of the C++ `IBinder`
190/// class which are internal implementation details.
191pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700192 /// Is this object still alive?
193 fn is_binder_alive(&self) -> bool;
194
195 /// Send a ping transaction to this object
196 fn ping_binder(&mut self) -> Result<()>;
197
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700198 /// Indicate that the service intends to receive caller security contexts.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800199 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700200 fn set_requesting_sid(&mut self, enable: bool);
201
Stephen Crane2a3c2502020-06-16 17:48:35 -0700202 /// Dump this object to the given file handle
203 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
204
205 /// Get a new interface that exposes additional extension functionality, if
206 /// available.
207 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
208
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000209 /// Create a Parcel that can be used with `submit_transact`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000210 fn prepare_transact(&self) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000211
Stephen Crane2a3c2502020-06-16 17:48:35 -0700212 /// Perform a generic operation with the object.
213 ///
Alice Ryhl8618c482021-11-09 15:35:35 +0000214 /// The provided [`Parcel`] must have been created by a call to
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000215 /// `prepare_transact` on the same binder.
216 ///
217 /// # Arguments
218 ///
219 /// * `code` - Transaction code for the operation.
Alice Ryhl8618c482021-11-09 15:35:35 +0000220 /// * `data` - [`Parcel`] with input data.
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000221 /// * `flags` - Transaction flags, e.g. marking the transaction as
222 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
223 fn submit_transact(
224 &self,
225 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000226 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000227 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000228 ) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000229
230 /// Perform a generic operation with the object. This is a convenience
231 /// method that internally calls `prepare_transact` followed by
232 /// `submit_transact.
233 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700234 /// # Arguments
235 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700236 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000237 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000238 /// * `input_callback` A callback for building the `Parcel`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000239 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
Stephen Crane2a3c2502020-06-16 17:48:35 -0700240 &self,
241 code: TransactionCode,
242 flags: TransactionFlags,
243 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000244 ) -> Result<Parcel> {
245 let mut parcel = self.prepare_transact()?;
Alice Ryhl8618c482021-11-09 15:35:35 +0000246 input_callback(parcel.borrowed())?;
247 self.submit_transact(code, parcel, flags)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000248 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000249}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700250
Andrew Walbran12400d82021-03-04 17:04:34 +0000251/// Interface of binder local or remote objects.
252///
253/// This trait corresponds to the parts of the interface of the C++ `IBinder`
254/// class which are public.
255pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700256 /// Register the recipient for a notification if this binder
257 /// goes away. If this binder object unexpectedly goes away
258 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000259 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700260 ///
261 /// You will only receive death notifications for remote binders,
262 /// as local binders by definition can't die without you dying as well.
263 /// Trying to use this function on a local binder will result in an
264 /// INVALID_OPERATION code being returned and nothing happening.
265 ///
266 /// This link always holds a weak reference to its recipient.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700267 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
268
269 /// Remove a previously registered death notification.
270 /// The recipient will no longer be called if this object
271 /// dies.
272 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
273}
274
275/// Opaque reference to the type of a Binder interface.
276///
277/// This object encapsulates the Binder interface descriptor string, along with
278/// the binder transaction callback, if the class describes a local service.
279///
280/// A Binder remotable object may only have a single interface class, and any
281/// given object can only be associated with one class. Two objects with
282/// different classes are incompatible, even if both classes have the same
283/// interface descriptor.
284#[derive(Copy, Clone, PartialEq, Eq)]
285pub struct InterfaceClass(*const sys::AIBinder_Class);
286
287impl InterfaceClass {
288 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
289 ///
290 /// Note: the returned pointer will not be constant. Calling this method
291 /// multiple times for the same type will result in distinct class
292 /// pointers. A static getter for this value is implemented in
293 /// [`declare_binder_interface!`].
294 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
295 let descriptor = CString::new(I::get_descriptor()).unwrap();
296 let ptr = unsafe {
297 // Safety: `AIBinder_Class_define` expects a valid C string, and
298 // three valid callback functions, all non-null pointers. The C
299 // string is copied and need not be valid for longer than the call,
300 // so we can drop it after the call. We can safely assign null to
301 // the onDump and handleShellCommand callbacks as long as the class
302 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
303 // be a NULL pointer. Rust retains ownership of the pointer after it
304 // is defined.
305 let class = sys::AIBinder_Class_define(
306 descriptor.as_ptr(),
307 Some(I::on_create),
308 Some(I::on_destroy),
309 Some(I::on_transact),
310 );
311 if class.is_null() {
312 panic!("Expected non-null class pointer from AIBinder_Class_define!");
313 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700314 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700315 sys::AIBinder_Class_setHandleShellCommand(class, None);
316 class
317 };
318 InterfaceClass(ptr)
319 }
320
321 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
322 /// pointer.
323 ///
324 /// # Safety
325 ///
326 /// This function is safe iff `ptr` is a valid, non-null pointer to an
327 /// `AIBinder_Class`.
328 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
329 InterfaceClass(ptr)
330 }
Stephen Crane669deb62020-09-10 17:31:39 -0700331
332 /// Get the interface descriptor string of this class.
333 pub fn get_descriptor(&self) -> String {
334 unsafe {
335 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
336 // is always a two-byte null terminated sequence of u16s. Thus, we
337 // can continue reading from the pointer until we hit a null value,
338 // and this pointer can be a valid slice if the slice length is <=
339 // the number of u16 elements before the null terminator.
340
341 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000342 CStr::from_ptr(raw_descriptor)
343 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700344 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
345 .into()
346 }
347 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700348}
349
350impl From<InterfaceClass> for *const sys::AIBinder_Class {
351 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
352 class.0
353 }
354}
355
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800356/// Strong reference to a binder object
357pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
358
359impl<I: FromIBinder + ?Sized> Strong<I> {
360 /// Create a new strong reference to the provided binder object
361 pub fn new(binder: Box<I>) -> Self {
362 Self(binder)
363 }
364
365 /// Construct a new weak reference to this binder
366 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
367 Weak::new(this)
368 }
Alice Ryhlc1736842021-11-23 12:38:51 +0000369
370 /// Convert this synchronous binder handle into an asynchronous one.
371 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
372 where
373 I: ToAsyncInterface<P>,
374 {
375 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder
376 // object is also valid for the target type.
377 FromIBinder::try_from(self.0.as_binder()).unwrap()
378 }
379
380 /// Convert this asynchronous binder handle into a synchronous one.
381 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
382 where
383 I: ToSyncInterface,
384 {
385 // By implementing the ToSyncInterface trait, it is guaranteed that the binder
386 // object is also valid for the target type.
387 FromIBinder::try_from(self.0.as_binder()).unwrap()
388 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800389}
390
391impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
392 fn clone(&self) -> Self {
393 // Since we hold a strong reference, we should always be able to create
394 // a new strong reference to the same interface type, so try_from()
395 // should never fail here.
396 FromIBinder::try_from(self.0.as_binder()).unwrap()
397 }
398}
399
400impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
401 fn borrow(&self) -> &I {
402 &self.0
403 }
404}
405
406impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
407 fn as_ref(&self) -> &I {
408 &self.0
409 }
410}
411
412impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
413 type Target = I;
414
415 fn deref(&self) -> &Self::Target {
416 &self.0
417 }
418}
419
420impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
421 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
422 fmt::Debug::fmt(&**self, f)
423 }
424}
425
426impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
427 fn cmp(&self, other: &Self) -> Ordering {
428 self.0.as_binder().cmp(&other.0.as_binder())
429 }
430}
431
432impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
433 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
434 self.0.as_binder().partial_cmp(&other.0.as_binder())
435 }
436}
437
438impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
439 fn eq(&self, other: &Self) -> bool {
440 self.0.as_binder().eq(&other.0.as_binder())
441 }
442}
443
444impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
445
446/// Weak reference to a binder object
447#[derive(Debug)]
448pub struct Weak<I: FromIBinder + ?Sized> {
449 weak_binder: WpIBinder,
450 interface_type: PhantomData<I>,
451}
452
453impl<I: FromIBinder + ?Sized> Weak<I> {
454 /// Construct a new weak reference from a strong reference
455 fn new(binder: &Strong<I>) -> Self {
456 let weak_binder = binder.as_binder().downgrade();
457 Weak {
458 weak_binder,
459 interface_type: PhantomData,
460 }
461 }
462
463 /// Upgrade this weak reference to a strong reference if the binder object
464 /// is still alive
465 pub fn upgrade(&self) -> Result<Strong<I>> {
466 self.weak_binder
467 .promote()
468 .ok_or(StatusCode::DEAD_OBJECT)
469 .and_then(FromIBinder::try_from)
470 }
471}
472
473impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
474 fn clone(&self) -> Self {
475 Self {
476 weak_binder: self.weak_binder.clone(),
477 interface_type: PhantomData,
478 }
479 }
480}
481
482impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
483 fn cmp(&self, other: &Self) -> Ordering {
484 self.weak_binder.cmp(&other.weak_binder)
485 }
486}
487
488impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
489 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
490 self.weak_binder.partial_cmp(&other.weak_binder)
491 }
492}
493
494impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
495 fn eq(&self, other: &Self) -> bool {
496 self.weak_binder == other.weak_binder
497 }
498}
499
500impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
501
Stephen Crane2a3c2502020-06-16 17:48:35 -0700502/// Create a function implementing a static getter for an interface class.
503///
504/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
505/// [`Interface`]) must have global, static class that uniquely identifies
506/// it. This macro implements an [`InterfaceClass`] getter to simplify these
507/// implementations.
508///
509/// The type of a structure that implements [`InterfaceClassMethods`] must be
510/// passed to this macro. For local services, this should be `Binder<Self>`
511/// since [`Binder`] implements [`InterfaceClassMethods`].
512///
513/// # Examples
514///
515/// When implementing a local [`Remotable`] service `ExampleService`, the
516/// `get_class` method is required in the [`Remotable`] impl block. This macro
517/// should be used as follows to implement this functionality:
518///
519/// ```rust
520/// impl Remotable for ExampleService {
521/// fn get_descriptor() -> &'static str {
522/// "android.os.IExampleInterface"
523/// }
524///
525/// fn on_transact(
526/// &self,
527/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000528/// data: &BorrowedParcel,
529/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700530/// ) -> Result<()> {
531/// // ...
532/// }
533///
534/// binder_fn_get_class!(Binder<Self>);
535/// }
536/// ```
537macro_rules! binder_fn_get_class {
538 ($class:ty) => {
539 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
540 };
541
542 ($constructor:expr) => {
543 fn get_class() -> $crate::InterfaceClass {
544 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
545 static mut CLASS: Option<$crate::InterfaceClass> = None;
546
547 CLASS_INIT.call_once(|| unsafe {
548 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
549 // variable, and therefore is thread-safe, as it can only occur
550 // once.
551 CLASS = Some($constructor);
552 });
553 unsafe {
554 // Safety: The `CLASS` variable can only be mutated once, above,
555 // and is subsequently safe to read from any thread.
556 CLASS.unwrap()
557 }
558 }
559 };
560}
561
562pub trait InterfaceClassMethods {
563 /// Get the interface descriptor string for this object type.
564 fn get_descriptor() -> &'static str
565 where
566 Self: Sized;
567
568 /// Called during construction of a new `AIBinder` object of this interface
569 /// class.
570 ///
571 /// The opaque pointer parameter will be the parameter provided to
572 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
573 /// `AIBinder` object.
574 ///
575 /// # Safety
576 ///
577 /// Callback called from C++. The parameter argument provided to
578 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
579 /// will take ownership of the returned pointer, which it will free via
580 /// `on_destroy`.
581 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
582
583 /// Called when a transaction needs to be processed by the local service
584 /// implementation.
585 ///
586 /// # Safety
587 ///
588 /// Callback called from C++. The `binder` parameter must be a valid pointer
589 /// to a binder object of this class with userdata initialized via this
590 /// class's `on_create`. The parcel parameters must be valid pointers to
591 /// parcel objects.
592 unsafe extern "C" fn on_transact(
593 binder: *mut sys::AIBinder,
594 code: u32,
595 data: *const sys::AParcel,
596 reply: *mut sys::AParcel,
597 ) -> status_t;
598
599 /// Called whenever an `AIBinder` object is no longer referenced and needs
600 /// to be destroyed.
601 ///
602 /// # Safety
603 ///
604 /// Callback called from C++. The opaque pointer parameter must be the value
605 /// returned by `on_create` for this class. This function takes ownership of
606 /// the provided pointer and destroys it.
607 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700608
609 /// Called to handle the `dump` transaction.
610 ///
611 /// # Safety
612 ///
613 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
614 /// contains a `T` pointer in its user data. fd should be a non-owned file
615 /// descriptor, and args must be an array of null-terminated string
616 /// poiinters with length num_args.
617 unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700618}
619
620/// Interface for transforming a generic SpIBinder into a specific remote
621/// interface trait.
622///
623/// # Example
624///
625/// For Binder interface `IFoo`, the following implementation should be made:
626/// ```no_run
627/// # use binder::{FromIBinder, SpIBinder, Result};
628/// # trait IFoo {}
629/// impl FromIBinder for dyn IFoo {
630/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
631/// // ...
632/// # Err(binder::StatusCode::OK)
633/// }
634/// }
635/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800636pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700637 /// Try to interpret a generic Binder object as this interface.
638 ///
639 /// Returns a trait object for the `Self` interface if this object
640 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800641 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700642}
643
644/// Trait for transparent Rust wrappers around android C++ native types.
645///
646/// The pointer return by this trait's methods should be immediately passed to
647/// C++ and not stored by Rust. The pointer is valid only as long as the
648/// underlying C++ object is alive, so users must be careful to take this into
649/// account, as Rust cannot enforce this.
650///
651/// # Safety
652///
653/// For this trait to be a correct implementation, `T` must be a valid android
654/// C++ type. Since we cannot constrain this via the type system, this trait is
655/// marked as unsafe.
656pub unsafe trait AsNative<T> {
657 /// Return a pointer to the native version of `self`
658 fn as_native(&self) -> *const T;
659
660 /// Return a mutable pointer to the native version of `self`
661 fn as_native_mut(&mut self) -> *mut T;
662}
663
664unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
665 fn as_native(&self) -> *const T {
666 self.as_ref().map_or(ptr::null(), |v| v.as_native())
667 }
668
669 fn as_native_mut(&mut self) -> *mut T {
670 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
671 }
672}
673
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000674/// The features to enable when creating a native Binder.
675///
676/// This should always be initialised with a default value, e.g.:
677/// ```
678/// # use binder::BinderFeatures;
679/// BinderFeatures {
680/// set_requesting_sid: true,
681/// ..BinderFeatures::default(),
682/// }
683/// ```
684#[derive(Clone, Debug, Default, Eq, PartialEq)]
685pub struct BinderFeatures {
686 /// Indicates that the service intends to receive caller security contexts. This must be true
687 /// for `ThreadState::with_calling_sid` to work.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800688 #[cfg(not(android_vndk))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000689 pub set_requesting_sid: bool,
690 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
691 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
692 // expressions entirely.
693 #[doc(hidden)]
694 pub _non_exhaustive: (),
695}
696
Stephen Crane2a3c2502020-06-16 17:48:35 -0700697/// Declare typed interfaces for a binder object.
698///
699/// Given an interface trait and descriptor string, create a native and remote
700/// proxy wrapper for this interface. The native service object (`$native`)
701/// implements `Remotable` and will dispatch to the function `$on_transact` to
702/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
703/// objects for this interface and can optionally contain additional fields.
704///
705/// Assuming the interface trait is `Interface`, `$on_transact` function must
706/// have the following type:
707///
708/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000709/// # use binder::{Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700710/// # trait Placeholder {
711/// fn on_transact(
712/// service: &dyn Interface,
713/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000714/// data: &BorrowedParcel,
715/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700716/// ) -> binder::Result<()>;
717/// # }
718/// ```
719///
720/// # Examples
721///
722/// The following example declares the local service type `BnServiceManager` and
723/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
724/// proxy respectively) for the `IServiceManager` Binder interface. The
725/// interfaces will be identified by the descriptor string
726/// "android.os.IServiceManager". The local service will dispatch transactions
727/// using the provided function, `on_transact`.
728///
729/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000730/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700731///
732/// pub trait IServiceManager: Interface {
733/// // remote methods...
734/// }
735///
736/// declare_binder_interface! {
737/// IServiceManager["android.os.IServiceManager"] {
738/// native: BnServiceManager(on_transact),
739/// proxy: BpServiceManager,
740/// }
741/// }
742///
743/// fn on_transact(
744/// service: &dyn IServiceManager,
745/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000746/// data: &BorrowedParcel,
747/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700748/// ) -> binder::Result<()> {
749/// // ...
750/// Ok(())
751/// }
752///
753/// impl IServiceManager for BpServiceManager {
754/// // parceling/unparceling code for the IServiceManager emitted here
755/// }
756///
757/// impl IServiceManager for Binder<BnServiceManager> {
758/// // Forward calls to local implementation
759/// }
760/// ```
761#[macro_export]
762macro_rules! declare_binder_interface {
763 {
764 $interface:path[$descriptor:expr] {
765 native: $native:ident($on_transact:path),
766 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000767 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700768 }
769 } => {
770 $crate::declare_binder_interface! {
771 $interface[$descriptor] {
772 native: $native($on_transact),
773 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000774 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800775 stability: $crate::Stability::default(),
776 }
777 }
778 };
779
780 {
781 $interface:path[$descriptor:expr] {
782 native: $native:ident($on_transact:path),
783 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000784 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800785 stability: $stability:expr,
786 }
787 } => {
788 $crate::declare_binder_interface! {
789 $interface[$descriptor] {
790 native: $native($on_transact),
791 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000792 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800793 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700794 }
795 }
796 };
797
798 {
799 $interface:path[$descriptor:expr] {
800 native: $native:ident($on_transact:path),
801 proxy: $proxy:ident {
802 $($fname:ident: $fty:ty = $finit:expr),*
803 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000804 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700805 }
806 } => {
807 $crate::declare_binder_interface! {
808 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800809 native: $native($on_transact),
810 proxy: $proxy {
811 $($fname: $fty = $finit),*
812 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000813 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800814 stability: $crate::Stability::default(),
815 }
816 }
817 };
818
819 {
820 $interface:path[$descriptor:expr] {
821 native: $native:ident($on_transact:path),
822 proxy: $proxy:ident {
823 $($fname:ident: $fty:ty = $finit:expr),*
824 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000825 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800826 stability: $stability:expr,
827 }
828 } => {
829 $crate::declare_binder_interface! {
830 $interface[$descriptor] {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700831 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
832 native: $native($on_transact),
833 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
834 proxy: $proxy {
835 $($fname: $fty = $finit),*
836 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000837 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800838 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700839 }
840 }
841 };
842
843 {
844 $interface:path[$descriptor:expr] {
845 @doc[$native_doc:expr]
846 native: $native:ident($on_transact:path),
847
848 @doc[$proxy_doc:expr]
849 proxy: $proxy:ident {
850 $($fname:ident: $fty:ty = $finit:expr),*
851 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800852
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000853 $( async: $async_interface:ident, )?
854
Stephen Craneff7f03a2021-02-25 16:04:22 -0800855 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700856 }
857 } => {
858 #[doc = $proxy_doc]
859 pub struct $proxy {
860 binder: $crate::SpIBinder,
861 $($fname: $fty,)*
862 }
863
864 impl $crate::Interface for $proxy {
865 fn as_binder(&self) -> $crate::SpIBinder {
866 self.binder.clone()
867 }
868 }
869
870 impl $crate::Proxy for $proxy
871 where
872 $proxy: $interface,
873 {
874 fn get_descriptor() -> &'static str {
875 $descriptor
876 }
877
878 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700879 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700880 }
881 }
882
883 #[doc = $native_doc]
884 #[repr(transparent)]
885 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
886
887 impl $native {
888 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000889 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
890 let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
Janis Danisevskis1323d512021-11-09 07:48:08 -0800891 #[cfg(not(android_vndk))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000892 $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800893 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700894 }
895 }
896
897 impl $crate::Remotable for $native {
898 fn get_descriptor() -> &'static str {
899 $descriptor
900 }
901
Alice Ryhl8618c482021-11-09 15:35:35 +0000902 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::BorrowedParcel<'_>, reply: &mut $crate::BorrowedParcel<'_>) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700903 match $on_transact(&*self.0, code, data, reply) {
904 // The C++ backend converts UNEXPECTED_NULL into an exception
905 Err($crate::StatusCode::UNEXPECTED_NULL) => {
906 let status = $crate::Status::new_exception(
907 $crate::ExceptionCode::NULL_POINTER,
908 None,
909 );
910 reply.write(&status)
911 },
912 result => result
913 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700914 }
915
Stephen Crane2a3297f2021-06-11 16:48:10 -0700916 fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> {
917 self.0.dump(file, args)
918 }
919
Stephen Crane2a3c2502020-06-16 17:48:35 -0700920 fn get_class() -> $crate::InterfaceClass {
921 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
922 static mut CLASS: Option<$crate::InterfaceClass> = None;
923
924 CLASS_INIT.call_once(|| unsafe {
925 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
926 // variable, and therefore is thread-safe, as it can only occur
927 // once.
928 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
929 });
930 unsafe {
931 // Safety: The `CLASS` variable can only be mutated once, above,
932 // and is subsequently safe to read from any thread.
933 CLASS.unwrap()
934 }
935 }
936 }
937
938 impl $crate::FromIBinder for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800939 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700940 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700941
942 let existing_class = ibinder.get_class();
943 if let Some(class) = existing_class {
944 if class != <$native as $crate::Remotable>::get_class() &&
945 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
946 {
947 // The binder object's descriptor string matches what we
948 // expect. We still need to treat this local or already
949 // associated object as remote, because we can't cast it
950 // into a Rust service object without a matching class
951 // pointer.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800952 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700953 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700954 }
955
Stephen Crane669deb62020-09-10 17:31:39 -0700956 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
957 let service: $crate::Result<$crate::Binder<$native>> =
958 std::convert::TryFrom::try_from(ibinder.clone());
959 if let Ok(service) = service {
960 // We were able to associate with our expected class and
961 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800962 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700963 } else {
964 // Service is remote
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800965 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700966 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000967 }
Stephen Crane669deb62020-09-10 17:31:39 -0700968
969 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700970 }
971 }
972
973 impl $crate::parcel::Serialize for dyn $interface + '_
974 where
Stephen Craned58bce02020-07-07 12:26:02 -0700975 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700976 {
Alice Ryhl8618c482021-11-09 15:35:35 +0000977 fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700978 let binder = $crate::Interface::as_binder(self);
979 parcel.write(&binder)
980 }
981 }
982
983 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
Alice Ryhl8618c482021-11-09 15:35:35 +0000984 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700985 parcel.write(&this.map($crate::Interface::as_binder))
986 }
987 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700988
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000989 impl std::fmt::Debug for dyn $interface + '_ {
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700990 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
991 f.pad(stringify!($interface))
992 }
993 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700994
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800995 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700996 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800997 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700998 fn to_owned(&self) -> Self::Owned {
999 self.as_binder().into_interface()
1000 .expect(concat!("Error cloning interface ", stringify!($interface)))
1001 }
1002 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001003
1004 $(
1005 // Async interface trait implementations.
1006 impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
1007 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $async_interface<P>>> {
1008 use $crate::AssociateClass;
1009
1010 let existing_class = ibinder.get_class();
1011 if let Some(class) = existing_class {
1012 if class != <$native as $crate::Remotable>::get_class() &&
1013 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
1014 {
1015 // The binder object's descriptor string matches what we
1016 // expect. We still need to treat this local or already
1017 // associated object as remote, because we can't cast it
1018 // into a Rust service object without a matching class
1019 // pointer.
1020 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
1021 }
1022 }
1023
1024 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
1025 let service: $crate::Result<$crate::Binder<$native>> =
1026 std::convert::TryFrom::try_from(ibinder.clone());
1027 if let Ok(service) = service {
1028 // We were able to associate with our expected class and
1029 // the service is local.
1030 todo!()
1031 //return Ok($crate::Strong::new(Box::new(service)));
1032 } else {
1033 // Service is remote
1034 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
1035 }
1036 }
1037
1038 Err($crate::StatusCode::BAD_TYPE.into())
1039 }
1040 }
1041
1042 impl<P: $crate::BinderAsyncPool> $crate::parcel::Serialize for dyn $async_interface<P> + '_ {
Alice Ryhl8618c482021-11-09 15:35:35 +00001043 fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001044 let binder = $crate::Interface::as_binder(self);
1045 parcel.write(&binder)
1046 }
1047 }
1048
1049 impl<P: $crate::BinderAsyncPool> $crate::parcel::SerializeOption for dyn $async_interface<P> + '_ {
Alice Ryhl8618c482021-11-09 15:35:35 +00001050 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001051 parcel.write(&this.map($crate::Interface::as_binder))
1052 }
1053 }
1054
1055 impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
1056 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1057 f.pad(stringify!($async_interface))
1058 }
1059 }
1060
1061 /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
1062 impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> {
1063 type Owned = $crate::Strong<dyn $async_interface<P>>;
1064 fn to_owned(&self) -> Self::Owned {
1065 self.as_binder().into_interface()
1066 .expect(concat!("Error cloning interface ", stringify!($async_interface)))
1067 }
1068 }
Alice Ryhlc1736842021-11-23 12:38:51 +00001069
1070 impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface {
1071 type Target = dyn $async_interface<P>;
1072 }
1073
1074 impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> {
1075 type Target = dyn $interface;
1076 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001077 )?
Stephen Crane2a3c2502020-06-16 17:48:35 -07001078 };
1079}
Andrei Homescu00eca712020-09-09 18:57:40 -07001080
1081/// Declare an AIDL enumeration.
1082///
1083/// This is mainly used internally by the AIDL compiler.
1084#[macro_export]
1085macro_rules! declare_binder_enum {
1086 {
Stephen Crane7bca1052021-10-25 17:52:51 -07001087 $( #[$attr:meta] )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001088 $enum:ident : [$backing:ty; $size:expr] {
Andrei Homescu00eca712020-09-09 18:57:40 -07001089 $( $name:ident = $value:expr, )*
1090 }
1091 } => {
Stephen Crane7bca1052021-10-25 17:52:51 -07001092 $( #[$attr] )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001093 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001094 #[allow(missing_docs)]
Andrei Homescu00eca712020-09-09 18:57:40 -07001095 pub struct $enum(pub $backing);
1096 impl $enum {
Stephen Crane7bca1052021-10-25 17:52:51 -07001097 $( #[allow(missing_docs)] pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001098
1099 #[inline(always)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001100 #[allow(missing_docs)]
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001101 pub const fn enum_values() -> [Self; $size] {
1102 [$(Self::$name),*]
1103 }
Andrei Homescu00eca712020-09-09 18:57:40 -07001104 }
1105
1106 impl $crate::parcel::Serialize for $enum {
Alice Ryhl8618c482021-11-09 15:35:35 +00001107 fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001108 parcel.write(&self.0)
1109 }
1110 }
1111
1112 impl $crate::parcel::SerializeArray for $enum {
Alice Ryhl8618c482021-11-09 15:35:35 +00001113 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001114 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
1115 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
1116 }
1117 }
1118
1119 impl $crate::parcel::Deserialize for $enum {
Alice Ryhl8618c482021-11-09 15:35:35 +00001120 fn deserialize(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Self> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001121 parcel.read().map(Self)
1122 }
1123 }
1124
1125 impl $crate::parcel::DeserializeArray for $enum {
Alice Ryhl8618c482021-11-09 15:35:35 +00001126 fn deserialize_array(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Option<Vec<Self>>> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001127 let v: Option<Vec<$backing>> =
1128 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
1129 Ok(v.map(|v| v.into_iter().map(Self).collect()))
1130 }
1131 }
1132 };
1133}