blob: 63c8684fa00e66190c22ac0b20cfa0f774c1eae1 [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};
Matthew Maurere268a9f2022-07-26 09:31:30 -070020use crate::parcel::{BorrowedParcel, 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;
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),
Matthew Maurere268a9f2022-07-26 09:31:30 -0700136 _ => Err(StatusCode::BAD_VALUE),
Andrei Homescuee132fa2021-09-03 02:36:17 +0000137 }
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.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700161 fn on_transact(
162 &self,
163 code: TransactionCode,
164 data: &BorrowedParcel<'_>,
165 reply: &mut BorrowedParcel<'_>,
166 ) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700167
Stephen Crane2a3297f2021-06-11 16:48:10 -0700168 /// Handle a request to invoke the dump transaction on this
169 /// object.
170 fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>;
171
Stephen Crane2a3c2502020-06-16 17:48:35 -0700172 /// Retrieve the class of this remote object.
173 ///
174 /// This method should always return the same InterfaceClass for the same
175 /// type.
176 fn get_class() -> InterfaceClass;
177}
178
Andrew Walbran12400d82021-03-04 17:04:34 +0000179/// First transaction code available for user commands (inclusive)
180pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
181/// Last transaction code available for user commands (inclusive)
182pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
183
184/// Corresponds to TF_ONE_WAY -- an asynchronous call.
185pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
186/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
187pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800188/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
189pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000190
191/// Internal interface of binder local or remote objects for making
192/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700193///
Andrew Walbran12400d82021-03-04 17:04:34 +0000194/// This trait corresponds to the parts of the interface of the C++ `IBinder`
195/// class which are internal implementation details.
196pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700197 /// Is this object still alive?
198 fn is_binder_alive(&self) -> bool;
199
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700200 /// Indicate that the service intends to receive caller security contexts.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800201 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700202 fn set_requesting_sid(&mut self, enable: bool);
203
Stephen Crane2a3c2502020-06-16 17:48:35 -0700204 /// Dump this object to the given file handle
205 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
206
207 /// Get a new interface that exposes additional extension functionality, if
208 /// available.
209 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
210
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000211 /// Create a Parcel that can be used with `submit_transact`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000212 fn prepare_transact(&self) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000213
Stephen Crane2a3c2502020-06-16 17:48:35 -0700214 /// Perform a generic operation with the object.
215 ///
Alice Ryhl8618c482021-11-09 15:35:35 +0000216 /// The provided [`Parcel`] must have been created by a call to
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000217 /// `prepare_transact` on the same binder.
218 ///
219 /// # Arguments
220 ///
221 /// * `code` - Transaction code for the operation.
Alice Ryhl8618c482021-11-09 15:35:35 +0000222 /// * `data` - [`Parcel`] with input data.
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000223 /// * `flags` - Transaction flags, e.g. marking the transaction as
224 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
225 fn submit_transact(
226 &self,
227 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000228 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000229 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000230 ) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000231
232 /// Perform a generic operation with the object. This is a convenience
233 /// method that internally calls `prepare_transact` followed by
234 /// `submit_transact.
235 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700236 /// # Arguments
237 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700238 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000239 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000240 /// * `input_callback` A callback for building the `Parcel`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000241 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
Stephen Crane2a3c2502020-06-16 17:48:35 -0700242 &self,
243 code: TransactionCode,
244 flags: TransactionFlags,
245 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000246 ) -> Result<Parcel> {
247 let mut parcel = self.prepare_transact()?;
Alice Ryhl8618c482021-11-09 15:35:35 +0000248 input_callback(parcel.borrowed())?;
249 self.submit_transact(code, parcel, flags)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000250 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000251}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700252
Andrew Walbran12400d82021-03-04 17:04:34 +0000253/// Interface of binder local or remote objects.
254///
255/// This trait corresponds to the parts of the interface of the C++ `IBinder`
256/// class which are public.
257pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700258 /// Register the recipient for a notification if this binder
259 /// goes away. If this binder object unexpectedly goes away
260 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000261 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700262 ///
263 /// You will only receive death notifications for remote binders,
264 /// as local binders by definition can't die without you dying as well.
265 /// Trying to use this function on a local binder will result in an
266 /// INVALID_OPERATION code being returned and nothing happening.
267 ///
268 /// This link always holds a weak reference to its recipient.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700269 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
270
271 /// Remove a previously registered death notification.
272 /// The recipient will no longer be called if this object
273 /// dies.
274 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
Stephen Crane61366d42022-01-20 17:45:34 -0800275
276 /// Send a ping transaction to this object
277 fn ping_binder(&mut self) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700278}
279
280/// Opaque reference to the type of a Binder interface.
281///
282/// This object encapsulates the Binder interface descriptor string, along with
283/// the binder transaction callback, if the class describes a local service.
284///
285/// A Binder remotable object may only have a single interface class, and any
286/// given object can only be associated with one class. Two objects with
287/// different classes are incompatible, even if both classes have the same
288/// interface descriptor.
289#[derive(Copy, Clone, PartialEq, Eq)]
290pub struct InterfaceClass(*const sys::AIBinder_Class);
291
292impl InterfaceClass {
293 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
294 ///
295 /// Note: the returned pointer will not be constant. Calling this method
296 /// multiple times for the same type will result in distinct class
297 /// pointers. A static getter for this value is implemented in
298 /// [`declare_binder_interface!`].
299 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
300 let descriptor = CString::new(I::get_descriptor()).unwrap();
301 let ptr = unsafe {
302 // Safety: `AIBinder_Class_define` expects a valid C string, and
303 // three valid callback functions, all non-null pointers. The C
304 // string is copied and need not be valid for longer than the call,
305 // so we can drop it after the call. We can safely assign null to
306 // the onDump and handleShellCommand callbacks as long as the class
307 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
308 // be a NULL pointer. Rust retains ownership of the pointer after it
309 // is defined.
310 let class = sys::AIBinder_Class_define(
311 descriptor.as_ptr(),
312 Some(I::on_create),
313 Some(I::on_destroy),
314 Some(I::on_transact),
315 );
316 if class.is_null() {
317 panic!("Expected non-null class pointer from AIBinder_Class_define!");
318 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700319 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700320 sys::AIBinder_Class_setHandleShellCommand(class, None);
321 class
322 };
323 InterfaceClass(ptr)
324 }
325
326 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
327 /// pointer.
328 ///
329 /// # Safety
330 ///
331 /// This function is safe iff `ptr` is a valid, non-null pointer to an
332 /// `AIBinder_Class`.
333 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
334 InterfaceClass(ptr)
335 }
Stephen Crane669deb62020-09-10 17:31:39 -0700336
337 /// Get the interface descriptor string of this class.
338 pub fn get_descriptor(&self) -> String {
339 unsafe {
340 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
341 // is always a two-byte null terminated sequence of u16s. Thus, we
342 // can continue reading from the pointer until we hit a null value,
343 // and this pointer can be a valid slice if the slice length is <=
344 // the number of u16 elements before the null terminator.
345
346 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000347 CStr::from_ptr(raw_descriptor)
348 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700349 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
350 .into()
351 }
352 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700353}
354
355impl From<InterfaceClass> for *const sys::AIBinder_Class {
356 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
357 class.0
358 }
359}
360
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800361/// Strong reference to a binder object
362pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
363
364impl<I: FromIBinder + ?Sized> Strong<I> {
365 /// Create a new strong reference to the provided binder object
366 pub fn new(binder: Box<I>) -> Self {
367 Self(binder)
368 }
369
370 /// Construct a new weak reference to this binder
371 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
372 Weak::new(this)
373 }
Alice Ryhlc1736842021-11-23 12:38:51 +0000374
375 /// Convert this synchronous binder handle into an asynchronous one.
376 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
377 where
378 I: ToAsyncInterface<P>,
379 {
380 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder
381 // object is also valid for the target type.
382 FromIBinder::try_from(self.0.as_binder()).unwrap()
383 }
384
385 /// Convert this asynchronous binder handle into a synchronous one.
386 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
387 where
388 I: ToSyncInterface,
389 {
390 // By implementing the ToSyncInterface trait, it is guaranteed that the binder
391 // object is also valid for the target type.
392 FromIBinder::try_from(self.0.as_binder()).unwrap()
393 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800394}
395
396impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
397 fn clone(&self) -> Self {
398 // Since we hold a strong reference, we should always be able to create
399 // a new strong reference to the same interface type, so try_from()
400 // should never fail here.
401 FromIBinder::try_from(self.0.as_binder()).unwrap()
402 }
403}
404
405impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
406 fn borrow(&self) -> &I {
407 &self.0
408 }
409}
410
411impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
412 fn as_ref(&self) -> &I {
413 &self.0
414 }
415}
416
417impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
418 type Target = I;
419
420 fn deref(&self) -> &Self::Target {
421 &self.0
422 }
423}
424
425impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
427 fmt::Debug::fmt(&**self, f)
428 }
429}
430
431impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
432 fn cmp(&self, other: &Self) -> Ordering {
433 self.0.as_binder().cmp(&other.0.as_binder())
434 }
435}
436
437impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
438 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
439 self.0.as_binder().partial_cmp(&other.0.as_binder())
440 }
441}
442
443impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
444 fn eq(&self, other: &Self) -> bool {
445 self.0.as_binder().eq(&other.0.as_binder())
446 }
447}
448
449impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
450
451/// Weak reference to a binder object
452#[derive(Debug)]
453pub struct Weak<I: FromIBinder + ?Sized> {
454 weak_binder: WpIBinder,
455 interface_type: PhantomData<I>,
456}
457
458impl<I: FromIBinder + ?Sized> Weak<I> {
459 /// Construct a new weak reference from a strong reference
460 fn new(binder: &Strong<I>) -> Self {
461 let weak_binder = binder.as_binder().downgrade();
Matthew Maurere268a9f2022-07-26 09:31:30 -0700462 Weak { weak_binder, interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800463 }
464
465 /// Upgrade this weak reference to a strong reference if the binder object
466 /// is still alive
467 pub fn upgrade(&self) -> Result<Strong<I>> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700468 self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from)
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800469 }
470}
471
472impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
473 fn clone(&self) -> Self {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700474 Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800475 }
476}
477
478impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
479 fn cmp(&self, other: &Self) -> Ordering {
480 self.weak_binder.cmp(&other.weak_binder)
481 }
482}
483
484impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
485 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
486 self.weak_binder.partial_cmp(&other.weak_binder)
487 }
488}
489
490impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
491 fn eq(&self, other: &Self) -> bool {
492 self.weak_binder == other.weak_binder
493 }
494}
495
496impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
497
Stephen Crane2a3c2502020-06-16 17:48:35 -0700498/// Create a function implementing a static getter for an interface class.
499///
500/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
501/// [`Interface`]) must have global, static class that uniquely identifies
502/// it. This macro implements an [`InterfaceClass`] getter to simplify these
503/// implementations.
504///
505/// The type of a structure that implements [`InterfaceClassMethods`] must be
506/// passed to this macro. For local services, this should be `Binder<Self>`
507/// since [`Binder`] implements [`InterfaceClassMethods`].
508///
509/// # Examples
510///
511/// When implementing a local [`Remotable`] service `ExampleService`, the
512/// `get_class` method is required in the [`Remotable`] impl block. This macro
513/// should be used as follows to implement this functionality:
514///
515/// ```rust
516/// impl Remotable for ExampleService {
517/// fn get_descriptor() -> &'static str {
518/// "android.os.IExampleInterface"
519/// }
520///
521/// fn on_transact(
522/// &self,
523/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000524/// data: &BorrowedParcel,
525/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700526/// ) -> Result<()> {
527/// // ...
528/// }
529///
530/// binder_fn_get_class!(Binder<Self>);
531/// }
532/// ```
533macro_rules! binder_fn_get_class {
534 ($class:ty) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000535 binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700536 };
537
538 ($constructor:expr) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000539 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700540 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000541 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700542
543 CLASS_INIT.call_once(|| unsafe {
544 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
545 // variable, and therefore is thread-safe, as it can only occur
546 // once.
547 CLASS = Some($constructor);
548 });
549 unsafe {
550 // Safety: The `CLASS` variable can only be mutated once, above,
551 // and is subsequently safe to read from any thread.
552 CLASS.unwrap()
553 }
554 }
555 };
556}
557
558pub trait InterfaceClassMethods {
559 /// Get the interface descriptor string for this object type.
560 fn get_descriptor() -> &'static str
561 where
562 Self: Sized;
563
564 /// Called during construction of a new `AIBinder` object of this interface
565 /// class.
566 ///
567 /// The opaque pointer parameter will be the parameter provided to
568 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
569 /// `AIBinder` object.
570 ///
571 /// # Safety
572 ///
573 /// Callback called from C++. The parameter argument provided to
574 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
575 /// will take ownership of the returned pointer, which it will free via
576 /// `on_destroy`.
577 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
578
579 /// Called when a transaction needs to be processed by the local service
580 /// implementation.
581 ///
582 /// # Safety
583 ///
584 /// Callback called from C++. The `binder` parameter must be a valid pointer
585 /// to a binder object of this class with userdata initialized via this
586 /// class's `on_create`. The parcel parameters must be valid pointers to
587 /// parcel objects.
588 unsafe extern "C" fn on_transact(
589 binder: *mut sys::AIBinder,
590 code: u32,
591 data: *const sys::AParcel,
592 reply: *mut sys::AParcel,
593 ) -> status_t;
594
595 /// Called whenever an `AIBinder` object is no longer referenced and needs
596 /// to be destroyed.
597 ///
598 /// # Safety
599 ///
600 /// Callback called from C++. The opaque pointer parameter must be the value
601 /// returned by `on_create` for this class. This function takes ownership of
602 /// the provided pointer and destroys it.
603 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700604
605 /// Called to handle the `dump` transaction.
606 ///
607 /// # Safety
608 ///
609 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
610 /// contains a `T` pointer in its user data. fd should be a non-owned file
611 /// descriptor, and args must be an array of null-terminated string
612 /// poiinters with length num_args.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700613 unsafe extern "C" fn on_dump(
614 binder: *mut sys::AIBinder,
615 fd: i32,
616 args: *mut *const c_char,
617 num_args: u32,
618 ) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700619}
620
621/// Interface for transforming a generic SpIBinder into a specific remote
622/// interface trait.
623///
624/// # Example
625///
626/// For Binder interface `IFoo`, the following implementation should be made:
627/// ```no_run
628/// # use binder::{FromIBinder, SpIBinder, Result};
629/// # trait IFoo {}
630/// impl FromIBinder for dyn IFoo {
631/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
632/// // ...
633/// # Err(binder::StatusCode::OK)
634/// }
635/// }
636/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800637pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700638 /// Try to interpret a generic Binder object as this interface.
639 ///
640 /// Returns a trait object for the `Self` interface if this object
641 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800642 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700643}
644
645/// Trait for transparent Rust wrappers around android C++ native types.
646///
647/// The pointer return by this trait's methods should be immediately passed to
648/// C++ and not stored by Rust. The pointer is valid only as long as the
649/// underlying C++ object is alive, so users must be careful to take this into
650/// account, as Rust cannot enforce this.
651///
652/// # Safety
653///
654/// For this trait to be a correct implementation, `T` must be a valid android
655/// C++ type. Since we cannot constrain this via the type system, this trait is
656/// marked as unsafe.
657pub unsafe trait AsNative<T> {
658 /// Return a pointer to the native version of `self`
659 fn as_native(&self) -> *const T;
660
661 /// Return a mutable pointer to the native version of `self`
662 fn as_native_mut(&mut self) -> *mut T;
663}
664
665unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
666 fn as_native(&self) -> *const T {
667 self.as_ref().map_or(ptr::null(), |v| v.as_native())
668 }
669
670 fn as_native_mut(&mut self) -> *mut T {
671 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
672 }
673}
674
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000675/// The features to enable when creating a native Binder.
676///
677/// This should always be initialised with a default value, e.g.:
678/// ```
679/// # use binder::BinderFeatures;
680/// BinderFeatures {
681/// set_requesting_sid: true,
682/// ..BinderFeatures::default(),
683/// }
684/// ```
685#[derive(Clone, Debug, Default, Eq, PartialEq)]
686pub struct BinderFeatures {
687 /// Indicates that the service intends to receive caller security contexts. This must be true
688 /// for `ThreadState::with_calling_sid` to work.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800689 #[cfg(not(android_vndk))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000690 pub set_requesting_sid: bool,
691 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
692 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
693 // expressions entirely.
694 #[doc(hidden)]
695 pub _non_exhaustive: (),
696}
697
Stephen Crane2a3c2502020-06-16 17:48:35 -0700698/// Declare typed interfaces for a binder object.
699///
700/// Given an interface trait and descriptor string, create a native and remote
701/// proxy wrapper for this interface. The native service object (`$native`)
702/// implements `Remotable` and will dispatch to the function `$on_transact` to
703/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
704/// objects for this interface and can optionally contain additional fields.
705///
706/// Assuming the interface trait is `Interface`, `$on_transact` function must
707/// have the following type:
708///
709/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000710/// # use binder::{Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700711/// # trait Placeholder {
712/// fn on_transact(
713/// service: &dyn Interface,
714/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000715/// data: &BorrowedParcel,
716/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700717/// ) -> binder::Result<()>;
718/// # }
719/// ```
720///
721/// # Examples
722///
723/// The following example declares the local service type `BnServiceManager` and
724/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
725/// proxy respectively) for the `IServiceManager` Binder interface. The
726/// interfaces will be identified by the descriptor string
727/// "android.os.IServiceManager". The local service will dispatch transactions
728/// using the provided function, `on_transact`.
729///
730/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000731/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700732///
733/// pub trait IServiceManager: Interface {
734/// // remote methods...
735/// }
736///
737/// declare_binder_interface! {
738/// IServiceManager["android.os.IServiceManager"] {
739/// native: BnServiceManager(on_transact),
740/// proxy: BpServiceManager,
741/// }
742/// }
743///
744/// fn on_transact(
745/// service: &dyn IServiceManager,
746/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000747/// data: &BorrowedParcel,
748/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700749/// ) -> binder::Result<()> {
750/// // ...
751/// Ok(())
752/// }
753///
754/// impl IServiceManager for BpServiceManager {
755/// // parceling/unparceling code for the IServiceManager emitted here
756/// }
757///
758/// impl IServiceManager for Binder<BnServiceManager> {
759/// // Forward calls to local implementation
760/// }
761/// ```
762#[macro_export]
763macro_rules! declare_binder_interface {
764 {
765 $interface:path[$descriptor:expr] {
766 native: $native:ident($on_transact:path),
767 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000768 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700769 }
770 } => {
771 $crate::declare_binder_interface! {
772 $interface[$descriptor] {
773 native: $native($on_transact),
774 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000775 $(async: $async_interface,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000776 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800777 }
778 }
779 };
780
781 {
782 $interface:path[$descriptor:expr] {
783 native: $native:ident($on_transact:path),
784 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000785 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800786 stability: $stability:expr,
787 }
788 } => {
789 $crate::declare_binder_interface! {
790 $interface[$descriptor] {
791 native: $native($on_transact),
792 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000793 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800794 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700795 }
796 }
797 };
798
799 {
800 $interface:path[$descriptor:expr] {
801 native: $native:ident($on_transact:path),
802 proxy: $proxy:ident {
803 $($fname:ident: $fty:ty = $finit:expr),*
804 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000805 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700806 }
807 } => {
808 $crate::declare_binder_interface! {
809 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800810 native: $native($on_transact),
811 proxy: $proxy {
812 $($fname: $fty = $finit),*
813 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000814 $(async: $async_interface,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000815 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800816 }
817 }
818 };
819
820 {
821 $interface:path[$descriptor:expr] {
822 native: $native:ident($on_transact:path),
823 proxy: $proxy:ident {
824 $($fname:ident: $fty:ty = $finit:expr),*
825 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000826 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800827 stability: $stability:expr,
828 }
829 } => {
830 $crate::declare_binder_interface! {
831 $interface[$descriptor] {
Stephen Cranef2735b42022-01-19 17:49:46 +0000832 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700833 native: $native($on_transact),
Stephen Cranef2735b42022-01-19 17:49:46 +0000834 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700835 proxy: $proxy {
836 $($fname: $fty = $finit),*
837 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000838 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800839 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700840 }
841 }
842 };
843
844 {
845 $interface:path[$descriptor:expr] {
846 @doc[$native_doc:expr]
847 native: $native:ident($on_transact:path),
848
849 @doc[$proxy_doc:expr]
850 proxy: $proxy:ident {
851 $($fname:ident: $fty:ty = $finit:expr),*
852 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800853
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000854 $( async: $async_interface:ident, )?
855
Stephen Craneff7f03a2021-02-25 16:04:22 -0800856 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700857 }
858 } => {
859 #[doc = $proxy_doc]
860 pub struct $proxy {
861 binder: $crate::SpIBinder,
862 $($fname: $fty,)*
863 }
864
865 impl $crate::Interface for $proxy {
866 fn as_binder(&self) -> $crate::SpIBinder {
867 self.binder.clone()
868 }
869 }
870
Stephen Cranef2735b42022-01-19 17:49:46 +0000871 impl $crate::binder_impl::Proxy for $proxy
Stephen Crane2a3c2502020-06-16 17:48:35 -0700872 where
873 $proxy: $interface,
874 {
875 fn get_descriptor() -> &'static str {
876 $descriptor
877 }
878
Stephen Cranef2735b42022-01-19 17:49:46 +0000879 fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> {
Stephen Crane669deb62020-09-10 17:31:39 -0700880 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700881 }
882 }
883
884 #[doc = $native_doc]
885 #[repr(transparent)]
886 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
887
888 impl $native {
889 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000890 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
Stephen Cranef2735b42022-01-19 17:49:46 +0000891 let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability);
Janis Danisevskis1323d512021-11-09 07:48:08 -0800892 #[cfg(not(android_vndk))]
Stephen Cranef2735b42022-01-19 17:49:46 +0000893 $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800894 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700895 }
896 }
897
Stephen Cranef2735b42022-01-19 17:49:46 +0000898 impl $crate::binder_impl::Remotable for $native {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700899 fn get_descriptor() -> &'static str {
900 $descriptor
901 }
902
Stephen Cranef2735b42022-01-19 17:49:46 +0000903 fn on_transact(&self, code: $crate::binder_impl::TransactionCode, data: &$crate::binder_impl::BorrowedParcel<'_>, reply: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu32814372020-08-20 15:36:08 -0700904 match $on_transact(&*self.0, code, data, reply) {
905 // The C++ backend converts UNEXPECTED_NULL into an exception
906 Err($crate::StatusCode::UNEXPECTED_NULL) => {
907 let status = $crate::Status::new_exception(
908 $crate::ExceptionCode::NULL_POINTER,
909 None,
910 );
911 reply.write(&status)
912 },
913 result => result
914 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700915 }
916
Stephen Cranef2735b42022-01-19 17:49:46 +0000917 fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700918 self.0.dump(file, args)
919 }
920
Stephen Cranef2735b42022-01-19 17:49:46 +0000921 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700922 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000923 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700924
925 CLASS_INIT.call_once(|| unsafe {
926 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
927 // variable, and therefore is thread-safe, as it can only occur
928 // once.
Stephen Cranef2735b42022-01-19 17:49:46 +0000929 CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700930 });
931 unsafe {
932 // Safety: The `CLASS` variable can only be mutated once, above,
933 // and is subsequently safe to read from any thread.
934 CLASS.unwrap()
935 }
936 }
937 }
938
939 impl $crate::FromIBinder for dyn $interface {
Stephen Cranef2735b42022-01-19 17:49:46 +0000940 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> {
941 use $crate::binder_impl::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700942
943 let existing_class = ibinder.get_class();
944 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +0000945 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
946 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Stephen Crane669deb62020-09-10 17:31:39 -0700947 {
948 // The binder object's descriptor string matches what we
949 // expect. We still need to treat this local or already
950 // associated object as remote, because we can't cast it
951 // into a Rust service object without a matching class
952 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +0000953 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700954 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700955 }
956
Stephen Cranef2735b42022-01-19 17:49:46 +0000957 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
958 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Stephen Crane669deb62020-09-10 17:31:39 -0700959 std::convert::TryFrom::try_from(ibinder.clone());
960 if let Ok(service) = service {
961 // We were able to associate with our expected class and
962 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800963 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700964 } else {
965 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +0000966 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700967 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000968 }
Stephen Crane669deb62020-09-10 17:31:39 -0700969
970 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700971 }
972 }
973
Stephen Cranef2735b42022-01-19 17:49:46 +0000974 impl $crate::binder_impl::Serialize for dyn $interface + '_
Stephen Crane2a3c2502020-06-16 17:48:35 -0700975 where
Stephen Craned58bce02020-07-07 12:26:02 -0700976 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700977 {
Stephen Cranef2735b42022-01-19 17:49:46 +0000978 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700979 let binder = $crate::Interface::as_binder(self);
980 parcel.write(&binder)
981 }
982 }
983
Stephen Cranef2735b42022-01-19 17:49:46 +0000984 impl $crate::binder_impl::SerializeOption for dyn $interface + '_ {
985 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700986 parcel.write(&this.map($crate::Interface::as_binder))
987 }
988 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700989
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000990 impl std::fmt::Debug for dyn $interface + '_ {
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700991 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
992 f.pad(stringify!($interface))
993 }
994 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700995
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800996 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700997 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800998 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700999 fn to_owned(&self) -> Self::Owned {
1000 self.as_binder().into_interface()
1001 .expect(concat!("Error cloning interface ", stringify!($interface)))
1002 }
1003 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001004
1005 $(
1006 // Async interface trait implementations.
1007 impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
Stephen Cranef2735b42022-01-19 17:49:46 +00001008 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
1009 use $crate::binder_impl::AssociateClass;
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001010
1011 let existing_class = ibinder.get_class();
1012 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +00001013 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
1014 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001015 {
1016 // The binder object's descriptor string matches what we
1017 // expect. We still need to treat this local or already
1018 // associated object as remote, because we can't cast it
1019 // into a Rust service object without a matching class
1020 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +00001021 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001022 }
1023 }
1024
Stephen Cranef2735b42022-01-19 17:49:46 +00001025 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
1026 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001027 std::convert::TryFrom::try_from(ibinder.clone());
1028 if let Ok(service) = service {
1029 // We were able to associate with our expected class and
1030 // the service is local.
1031 todo!()
1032 //return Ok($crate::Strong::new(Box::new(service)));
1033 } else {
1034 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +00001035 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001036 }
1037 }
1038
1039 Err($crate::StatusCode::BAD_TYPE.into())
1040 }
1041 }
1042
Stephen Cranef2735b42022-01-19 17:49:46 +00001043 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
1044 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001045 let binder = $crate::Interface::as_binder(self);
1046 parcel.write(&binder)
1047 }
1048 }
1049
Stephen Cranef2735b42022-01-19 17:49:46 +00001050 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
1051 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001052 parcel.write(&this.map($crate::Interface::as_binder))
1053 }
1054 }
1055
1056 impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
1057 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1058 f.pad(stringify!($async_interface))
1059 }
1060 }
1061
1062 /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
1063 impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> {
1064 type Owned = $crate::Strong<dyn $async_interface<P>>;
1065 fn to_owned(&self) -> Self::Owned {
1066 self.as_binder().into_interface()
1067 .expect(concat!("Error cloning interface ", stringify!($async_interface)))
1068 }
1069 }
Alice Ryhlc1736842021-11-23 12:38:51 +00001070
Stephen Cranef2735b42022-01-19 17:49:46 +00001071 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
Alice Ryhlc1736842021-11-23 12:38:51 +00001072 type Target = dyn $async_interface<P>;
1073 }
1074
Stephen Cranef2735b42022-01-19 17:49:46 +00001075 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
Alice Ryhlc1736842021-11-23 12:38:51 +00001076 type Target = dyn $interface;
1077 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001078 )?
Stephen Crane2a3c2502020-06-16 17:48:35 -07001079 };
1080}
Andrei Homescu00eca712020-09-09 18:57:40 -07001081
1082/// Declare an AIDL enumeration.
1083///
1084/// This is mainly used internally by the AIDL compiler.
1085#[macro_export]
1086macro_rules! declare_binder_enum {
1087 {
Stephen Crane7bca1052021-10-25 17:52:51 -07001088 $( #[$attr:meta] )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001089 $enum:ident : [$backing:ty; $size:expr] {
Jooyung Han70d92812022-03-18 15:29:54 +09001090 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001091 }
1092 } => {
Stephen Crane7bca1052021-10-25 17:52:51 -07001093 $( #[$attr] )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001094 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001095 #[allow(missing_docs)]
Andrei Homescu00eca712020-09-09 18:57:40 -07001096 pub struct $enum(pub $backing);
1097 impl $enum {
Jooyung Han70d92812022-03-18 15:29:54 +09001098 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001099
1100 #[inline(always)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001101 #[allow(missing_docs)]
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001102 pub const fn enum_values() -> [Self; $size] {
1103 [$(Self::$name),*]
1104 }
Andrei Homescu00eca712020-09-09 18:57:40 -07001105 }
1106
Stephen Cranef2735b42022-01-19 17:49:46 +00001107 impl $crate::binder_impl::Serialize for $enum {
1108 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001109 parcel.write(&self.0)
1110 }
1111 }
1112
Stephen Cranef2735b42022-01-19 17:49:46 +00001113 impl $crate::binder_impl::SerializeArray for $enum {
1114 fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001115 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
Stephen Cranef2735b42022-01-19 17:49:46 +00001116 <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel)
Andrei Homescu00eca712020-09-09 18:57:40 -07001117 }
1118 }
1119
Stephen Cranef2735b42022-01-19 17:49:46 +00001120 impl $crate::binder_impl::Deserialize for $enum {
1121 fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001122 parcel.read().map(Self)
1123 }
1124 }
1125
Stephen Cranef2735b42022-01-19 17:49:46 +00001126 impl $crate::binder_impl::DeserializeArray for $enum {
1127 fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001128 let v: Option<Vec<$backing>> =
Stephen Cranef2735b42022-01-19 17:49:46 +00001129 <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?;
Andrei Homescu00eca712020-09-09 18:57:40 -07001130 Ok(v.map(|v| v.into_iter().map(Self).collect()))
1131 }
1132 }
1133 };
1134}