blob: 993bdca4a5767e8c4abed976f3b39f0976705c0b [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.
Chariseeab53d0a2023-03-03 02:08:34 +0000103#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
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)
Chariseeab53d0a2023-03-03 02:08:34 +0000107 #[default]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800108 Local,
109
110 /// A Vendor Interface Object, which promises to be stable
111 Vintf,
112}
113
Andrei Homescuee132fa2021-09-03 02:36:17 +0000114impl From<Stability> for i32 {
115 fn from(stability: Stability) -> i32 {
116 use Stability::*;
117 match stability {
118 Local => 0,
119 Vintf => 1,
120 }
121 }
122}
123
124impl TryFrom<i32> for Stability {
125 type Error = StatusCode;
126 fn try_from(stability: i32) -> Result<Stability> {
127 use Stability::*;
128 match stability {
129 0 => Ok(Local),
130 1 => Ok(Vintf),
Matthew Maurere268a9f2022-07-26 09:31:30 -0700131 _ => Err(StatusCode::BAD_VALUE),
Andrei Homescuee132fa2021-09-03 02:36:17 +0000132 }
133 }
134}
135
Stephen Crane2a3c2502020-06-16 17:48:35 -0700136/// A local service that can be remotable via Binder.
137///
138/// An object that implement this interface made be made into a Binder service
139/// via `Binder::new(object)`.
140///
141/// This is a low-level interface that should normally be automatically
142/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
143/// the AIDL backend, users need only implement the high-level AIDL-defined
144/// interface. The AIDL compiler then generates a container struct that wraps
145/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -0700146pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700147 /// The Binder interface descriptor string.
148 ///
149 /// This string is a unique identifier for a Binder interface, and should be
150 /// the same between all implementations of that interface.
151 fn get_descriptor() -> &'static str;
152
153 /// Handle and reply to a request to invoke a transaction on this object.
154 ///
155 /// `reply` may be [`None`] if the sender does not expect a reply.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700156 fn on_transact(
157 &self,
158 code: TransactionCode,
159 data: &BorrowedParcel<'_>,
160 reply: &mut BorrowedParcel<'_>,
161 ) -> 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
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700195 /// Indicate that the service intends to receive caller security contexts.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800196 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700197 fn set_requesting_sid(&mut self, enable: bool);
198
Stephen Crane2a3c2502020-06-16 17:48:35 -0700199 /// Dump this object to the given file handle
200 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
201
202 /// Get a new interface that exposes additional extension functionality, if
203 /// available.
204 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
205
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000206 /// Create a Parcel that can be used with `submit_transact`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000207 fn prepare_transact(&self) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000208
Stephen Crane2a3c2502020-06-16 17:48:35 -0700209 /// Perform a generic operation with the object.
210 ///
Alice Ryhl8618c482021-11-09 15:35:35 +0000211 /// The provided [`Parcel`] must have been created by a call to
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000212 /// `prepare_transact` on the same binder.
213 ///
214 /// # Arguments
215 ///
216 /// * `code` - Transaction code for the operation.
Alice Ryhl8618c482021-11-09 15:35:35 +0000217 /// * `data` - [`Parcel`] with input data.
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000218 /// * `flags` - Transaction flags, e.g. marking the transaction as
219 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
220 fn submit_transact(
221 &self,
222 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000223 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000224 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000225 ) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000226
227 /// Perform a generic operation with the object. This is a convenience
228 /// method that internally calls `prepare_transact` followed by
229 /// `submit_transact.
230 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700231 /// # Arguments
232 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700233 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000234 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000235 /// * `input_callback` A callback for building the `Parcel`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000236 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
Stephen Crane2a3c2502020-06-16 17:48:35 -0700237 &self,
238 code: TransactionCode,
239 flags: TransactionFlags,
240 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000241 ) -> Result<Parcel> {
242 let mut parcel = self.prepare_transact()?;
Alice Ryhl8618c482021-11-09 15:35:35 +0000243 input_callback(parcel.borrowed())?;
244 self.submit_transact(code, parcel, flags)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000245 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000246}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700247
Andrew Walbran12400d82021-03-04 17:04:34 +0000248/// Interface of binder local or remote objects.
249///
250/// This trait corresponds to the parts of the interface of the C++ `IBinder`
251/// class which are public.
252pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700253 /// Register the recipient for a notification if this binder
254 /// goes away. If this binder object unexpectedly goes away
255 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000256 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700257 ///
258 /// You will only receive death notifications for remote binders,
259 /// as local binders by definition can't die without you dying as well.
260 /// Trying to use this function on a local binder will result in an
261 /// INVALID_OPERATION code being returned and nothing happening.
262 ///
Andrew Walbranfee58632023-06-22 17:36:48 +0000263 /// This link only holds a weak reference to its recipient. If the
264 /// `DeathRecipient` is dropped then it will be unlinked.
265 ///
266 /// Note that the notifications won't work if you don't first start at least
267 /// one Binder thread by calling
268 /// [`ProcessState::start_thread_pool`](crate::ProcessState::start_thread_pool)
269 /// or
270 /// [`ProcessState::join_thread_pool`](crate::ProcessState::join_thread_pool).
Stephen Crane2a3c2502020-06-16 17:48:35 -0700271 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
272
273 /// Remove a previously registered death notification.
274 /// The recipient will no longer be called if this object
275 /// dies.
276 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
Stephen Crane61366d42022-01-20 17:45:34 -0800277
278 /// Send a ping transaction to this object
279 fn ping_binder(&mut self) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700280}
281
282/// Opaque reference to the type of a Binder interface.
283///
284/// This object encapsulates the Binder interface descriptor string, along with
285/// the binder transaction callback, if the class describes a local service.
286///
287/// A Binder remotable object may only have a single interface class, and any
288/// given object can only be associated with one class. Two objects with
289/// different classes are incompatible, even if both classes have the same
290/// interface descriptor.
291#[derive(Copy, Clone, PartialEq, Eq)]
292pub struct InterfaceClass(*const sys::AIBinder_Class);
293
294impl InterfaceClass {
295 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
296 ///
297 /// Note: the returned pointer will not be constant. Calling this method
298 /// multiple times for the same type will result in distinct class
299 /// pointers. A static getter for this value is implemented in
300 /// [`declare_binder_interface!`].
301 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
302 let descriptor = CString::new(I::get_descriptor()).unwrap();
303 let ptr = unsafe {
304 // Safety: `AIBinder_Class_define` expects a valid C string, and
305 // three valid callback functions, all non-null pointers. The C
306 // string is copied and need not be valid for longer than the call,
307 // so we can drop it after the call. We can safely assign null to
308 // the onDump and handleShellCommand callbacks as long as the class
309 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
310 // be a NULL pointer. Rust retains ownership of the pointer after it
311 // is defined.
312 let class = sys::AIBinder_Class_define(
313 descriptor.as_ptr(),
314 Some(I::on_create),
315 Some(I::on_destroy),
316 Some(I::on_transact),
317 );
318 if class.is_null() {
319 panic!("Expected non-null class pointer from AIBinder_Class_define!");
320 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700321 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700322 sys::AIBinder_Class_setHandleShellCommand(class, None);
323 class
324 };
325 InterfaceClass(ptr)
326 }
327
328 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
329 /// pointer.
330 ///
331 /// # Safety
332 ///
333 /// This function is safe iff `ptr` is a valid, non-null pointer to an
334 /// `AIBinder_Class`.
335 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
336 InterfaceClass(ptr)
337 }
Stephen Crane669deb62020-09-10 17:31:39 -0700338
339 /// Get the interface descriptor string of this class.
340 pub fn get_descriptor(&self) -> String {
341 unsafe {
342 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
343 // is always a two-byte null terminated sequence of u16s. Thus, we
344 // can continue reading from the pointer until we hit a null value,
345 // and this pointer can be a valid slice if the slice length is <=
346 // the number of u16 elements before the null terminator.
347
348 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000349 CStr::from_ptr(raw_descriptor)
350 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700351 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
352 .into()
353 }
354 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700355}
356
357impl From<InterfaceClass> for *const sys::AIBinder_Class {
358 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
359 class.0
360 }
361}
362
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800363/// Strong reference to a binder object
364pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
365
366impl<I: FromIBinder + ?Sized> Strong<I> {
367 /// Create a new strong reference to the provided binder object
368 pub fn new(binder: Box<I>) -> Self {
369 Self(binder)
370 }
371
372 /// Construct a new weak reference to this binder
373 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
374 Weak::new(this)
375 }
Alice Ryhlc1736842021-11-23 12:38:51 +0000376
377 /// Convert this synchronous binder handle into an asynchronous one.
378 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
379 where
380 I: ToAsyncInterface<P>,
381 {
382 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder
383 // object is also valid for the target type.
384 FromIBinder::try_from(self.0.as_binder()).unwrap()
385 }
386
387 /// Convert this asynchronous binder handle into a synchronous one.
388 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
389 where
390 I: ToSyncInterface,
391 {
392 // By implementing the ToSyncInterface trait, it is guaranteed that the binder
393 // object is also valid for the target type.
394 FromIBinder::try_from(self.0.as_binder()).unwrap()
395 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800396}
397
398impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
399 fn clone(&self) -> Self {
400 // Since we hold a strong reference, we should always be able to create
401 // a new strong reference to the same interface type, so try_from()
402 // should never fail here.
403 FromIBinder::try_from(self.0.as_binder()).unwrap()
404 }
405}
406
407impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
408 fn borrow(&self) -> &I {
409 &self.0
410 }
411}
412
413impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
414 fn as_ref(&self) -> &I {
415 &self.0
416 }
417}
418
419impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
420 type Target = I;
421
422 fn deref(&self) -> &Self::Target {
423 &self.0
424 }
425}
426
427impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
428 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
429 fmt::Debug::fmt(&**self, f)
430 }
431}
432
433impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
434 fn cmp(&self, other: &Self) -> Ordering {
435 self.0.as_binder().cmp(&other.0.as_binder())
436 }
437}
438
439impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
440 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
441 self.0.as_binder().partial_cmp(&other.0.as_binder())
442 }
443}
444
445impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
446 fn eq(&self, other: &Self) -> bool {
447 self.0.as_binder().eq(&other.0.as_binder())
448 }
449}
450
451impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
452
453/// Weak reference to a binder object
454#[derive(Debug)]
455pub struct Weak<I: FromIBinder + ?Sized> {
456 weak_binder: WpIBinder,
457 interface_type: PhantomData<I>,
458}
459
460impl<I: FromIBinder + ?Sized> Weak<I> {
461 /// Construct a new weak reference from a strong reference
462 fn new(binder: &Strong<I>) -> Self {
463 let weak_binder = binder.as_binder().downgrade();
Matthew Maurere268a9f2022-07-26 09:31:30 -0700464 Weak { weak_binder, interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800465 }
466
467 /// Upgrade this weak reference to a strong reference if the binder object
468 /// is still alive
469 pub fn upgrade(&self) -> Result<Strong<I>> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700470 self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from)
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800471 }
472}
473
474impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
475 fn clone(&self) -> Self {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700476 Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800477 }
478}
479
480impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
481 fn cmp(&self, other: &Self) -> Ordering {
482 self.weak_binder.cmp(&other.weak_binder)
483 }
484}
485
486impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
487 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
488 self.weak_binder.partial_cmp(&other.weak_binder)
489 }
490}
491
492impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
493 fn eq(&self, other: &Self) -> bool {
494 self.weak_binder == other.weak_binder
495 }
496}
497
498impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
499
Stephen Crane2a3c2502020-06-16 17:48:35 -0700500/// Create a function implementing a static getter for an interface class.
501///
502/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
503/// [`Interface`]) must have global, static class that uniquely identifies
504/// it. This macro implements an [`InterfaceClass`] getter to simplify these
505/// implementations.
506///
507/// The type of a structure that implements [`InterfaceClassMethods`] must be
508/// passed to this macro. For local services, this should be `Binder<Self>`
509/// since [`Binder`] implements [`InterfaceClassMethods`].
510///
511/// # Examples
512///
513/// When implementing a local [`Remotable`] service `ExampleService`, the
514/// `get_class` method is required in the [`Remotable`] impl block. This macro
515/// should be used as follows to implement this functionality:
516///
517/// ```rust
518/// impl Remotable for ExampleService {
519/// fn get_descriptor() -> &'static str {
520/// "android.os.IExampleInterface"
521/// }
522///
523/// fn on_transact(
524/// &self,
525/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000526/// data: &BorrowedParcel,
527/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700528/// ) -> Result<()> {
529/// // ...
530/// }
531///
532/// binder_fn_get_class!(Binder<Self>);
533/// }
534/// ```
535macro_rules! binder_fn_get_class {
536 ($class:ty) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000537 binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700538 };
539
540 ($constructor:expr) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000541 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700542 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000543 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700544
545 CLASS_INIT.call_once(|| unsafe {
546 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
547 // variable, and therefore is thread-safe, as it can only occur
548 // once.
549 CLASS = Some($constructor);
550 });
551 unsafe {
552 // Safety: The `CLASS` variable can only be mutated once, above,
553 // and is subsequently safe to read from any thread.
554 CLASS.unwrap()
555 }
556 }
557 };
558}
559
560pub trait InterfaceClassMethods {
561 /// Get the interface descriptor string for this object type.
562 fn get_descriptor() -> &'static str
563 where
564 Self: Sized;
565
566 /// Called during construction of a new `AIBinder` object of this interface
567 /// class.
568 ///
569 /// The opaque pointer parameter will be the parameter provided to
570 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
571 /// `AIBinder` object.
572 ///
573 /// # Safety
574 ///
575 /// Callback called from C++. The parameter argument provided to
576 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
577 /// will take ownership of the returned pointer, which it will free via
578 /// `on_destroy`.
579 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
580
581 /// Called when a transaction needs to be processed by the local service
582 /// implementation.
583 ///
584 /// # Safety
585 ///
586 /// Callback called from C++. The `binder` parameter must be a valid pointer
587 /// to a binder object of this class with userdata initialized via this
588 /// class's `on_create`. The parcel parameters must be valid pointers to
589 /// parcel objects.
590 unsafe extern "C" fn on_transact(
591 binder: *mut sys::AIBinder,
592 code: u32,
593 data: *const sys::AParcel,
594 reply: *mut sys::AParcel,
595 ) -> status_t;
596
597 /// Called whenever an `AIBinder` object is no longer referenced and needs
598 /// to be destroyed.
599 ///
600 /// # Safety
601 ///
602 /// Callback called from C++. The opaque pointer parameter must be the value
603 /// returned by `on_create` for this class. This function takes ownership of
604 /// the provided pointer and destroys it.
605 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700606
607 /// Called to handle the `dump` transaction.
608 ///
609 /// # Safety
610 ///
611 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
612 /// contains a `T` pointer in its user data. fd should be a non-owned file
613 /// descriptor, and args must be an array of null-terminated string
614 /// poiinters with length num_args.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700615 unsafe extern "C" fn on_dump(
616 binder: *mut sys::AIBinder,
617 fd: i32,
618 args: *mut *const c_char,
619 num_args: u32,
620 ) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700621}
622
623/// Interface for transforming a generic SpIBinder into a specific remote
624/// interface trait.
625///
626/// # Example
627///
628/// For Binder interface `IFoo`, the following implementation should be made:
629/// ```no_run
630/// # use binder::{FromIBinder, SpIBinder, Result};
631/// # trait IFoo {}
632/// impl FromIBinder for dyn IFoo {
633/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
634/// // ...
635/// # Err(binder::StatusCode::OK)
636/// }
637/// }
638/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800639pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700640 /// Try to interpret a generic Binder object as this interface.
641 ///
642 /// Returns a trait object for the `Self` interface if this object
643 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800644 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700645}
646
647/// Trait for transparent Rust wrappers around android C++ native types.
648///
649/// The pointer return by this trait's methods should be immediately passed to
650/// C++ and not stored by Rust. The pointer is valid only as long as the
651/// underlying C++ object is alive, so users must be careful to take this into
652/// account, as Rust cannot enforce this.
653///
654/// # Safety
655///
656/// For this trait to be a correct implementation, `T` must be a valid android
657/// C++ type. Since we cannot constrain this via the type system, this trait is
658/// marked as unsafe.
659pub unsafe trait AsNative<T> {
660 /// Return a pointer to the native version of `self`
661 fn as_native(&self) -> *const T;
662
663 /// Return a mutable pointer to the native version of `self`
664 fn as_native_mut(&mut self) -> *mut T;
665}
666
667unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
668 fn as_native(&self) -> *const T {
669 self.as_ref().map_or(ptr::null(), |v| v.as_native())
670 }
671
672 fn as_native_mut(&mut self) -> *mut T {
673 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
674 }
675}
676
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000677/// The features to enable when creating a native Binder.
678///
679/// This should always be initialised with a default value, e.g.:
680/// ```
681/// # use binder::BinderFeatures;
682/// BinderFeatures {
683/// set_requesting_sid: true,
684/// ..BinderFeatures::default(),
685/// }
686/// ```
687#[derive(Clone, Debug, Default, Eq, PartialEq)]
688pub struct BinderFeatures {
689 /// Indicates that the service intends to receive caller security contexts. This must be true
690 /// for `ThreadState::with_calling_sid` to work.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800691 #[cfg(not(android_vndk))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000692 pub set_requesting_sid: bool,
693 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
694 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
695 // expressions entirely.
696 #[doc(hidden)]
697 pub _non_exhaustive: (),
698}
699
Stephen Crane2a3c2502020-06-16 17:48:35 -0700700/// Declare typed interfaces for a binder object.
701///
702/// Given an interface trait and descriptor string, create a native and remote
703/// proxy wrapper for this interface. The native service object (`$native`)
704/// implements `Remotable` and will dispatch to the function `$on_transact` to
705/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
706/// objects for this interface and can optionally contain additional fields.
707///
708/// Assuming the interface trait is `Interface`, `$on_transact` function must
709/// have the following type:
710///
711/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000712/// # use binder::{Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700713/// # trait Placeholder {
714/// fn on_transact(
715/// service: &dyn Interface,
716/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000717/// data: &BorrowedParcel,
718/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700719/// ) -> binder::Result<()>;
720/// # }
721/// ```
722///
723/// # Examples
724///
725/// The following example declares the local service type `BnServiceManager` and
726/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
727/// proxy respectively) for the `IServiceManager` Binder interface. The
728/// interfaces will be identified by the descriptor string
729/// "android.os.IServiceManager". The local service will dispatch transactions
730/// using the provided function, `on_transact`.
731///
732/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000733/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700734///
735/// pub trait IServiceManager: Interface {
736/// // remote methods...
737/// }
738///
739/// declare_binder_interface! {
740/// IServiceManager["android.os.IServiceManager"] {
741/// native: BnServiceManager(on_transact),
742/// proxy: BpServiceManager,
743/// }
744/// }
745///
746/// fn on_transact(
747/// service: &dyn IServiceManager,
748/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000749/// data: &BorrowedParcel,
750/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700751/// ) -> binder::Result<()> {
752/// // ...
753/// Ok(())
754/// }
755///
756/// impl IServiceManager for BpServiceManager {
757/// // parceling/unparceling code for the IServiceManager emitted here
758/// }
759///
760/// impl IServiceManager for Binder<BnServiceManager> {
761/// // Forward calls to local implementation
762/// }
763/// ```
764#[macro_export]
765macro_rules! declare_binder_interface {
766 {
767 $interface:path[$descriptor:expr] {
768 native: $native:ident($on_transact:path),
769 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000770 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700771 }
772 } => {
773 $crate::declare_binder_interface! {
774 $interface[$descriptor] {
775 native: $native($on_transact),
776 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000777 $(async: $async_interface,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000778 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800779 }
780 }
781 };
782
783 {
784 $interface:path[$descriptor:expr] {
785 native: $native:ident($on_transact:path),
786 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000787 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800788 stability: $stability:expr,
789 }
790 } => {
791 $crate::declare_binder_interface! {
792 $interface[$descriptor] {
793 native: $native($on_transact),
794 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000795 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800796 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700797 }
798 }
799 };
800
801 {
802 $interface:path[$descriptor:expr] {
803 native: $native:ident($on_transact:path),
804 proxy: $proxy:ident {
805 $($fname:ident: $fty:ty = $finit:expr),*
806 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000807 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700808 }
809 } => {
810 $crate::declare_binder_interface! {
811 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800812 native: $native($on_transact),
813 proxy: $proxy {
814 $($fname: $fty = $finit),*
815 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000816 $(async: $async_interface,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000817 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800818 }
819 }
820 };
821
822 {
823 $interface:path[$descriptor:expr] {
824 native: $native:ident($on_transact:path),
825 proxy: $proxy:ident {
826 $($fname:ident: $fty:ty = $finit:expr),*
827 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000828 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800829 stability: $stability:expr,
830 }
831 } => {
832 $crate::declare_binder_interface! {
833 $interface[$descriptor] {
Stephen Cranef2735b42022-01-19 17:49:46 +0000834 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700835 native: $native($on_transact),
Stephen Cranef2735b42022-01-19 17:49:46 +0000836 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700837 proxy: $proxy {
838 $($fname: $fty = $finit),*
839 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000840 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800841 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700842 }
843 }
844 };
845
846 {
847 $interface:path[$descriptor:expr] {
848 @doc[$native_doc:expr]
849 native: $native:ident($on_transact:path),
850
851 @doc[$proxy_doc:expr]
852 proxy: $proxy:ident {
853 $($fname:ident: $fty:ty = $finit:expr),*
854 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800855
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000856 $( async: $async_interface:ident, )?
857
Stephen Craneff7f03a2021-02-25 16:04:22 -0800858 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700859 }
860 } => {
861 #[doc = $proxy_doc]
862 pub struct $proxy {
863 binder: $crate::SpIBinder,
864 $($fname: $fty,)*
865 }
866
867 impl $crate::Interface for $proxy {
868 fn as_binder(&self) -> $crate::SpIBinder {
869 self.binder.clone()
870 }
871 }
872
Stephen Cranef2735b42022-01-19 17:49:46 +0000873 impl $crate::binder_impl::Proxy for $proxy
Stephen Crane2a3c2502020-06-16 17:48:35 -0700874 where
875 $proxy: $interface,
876 {
877 fn get_descriptor() -> &'static str {
878 $descriptor
879 }
880
Stephen Cranef2735b42022-01-19 17:49:46 +0000881 fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> {
Stephen Crane669deb62020-09-10 17:31:39 -0700882 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700883 }
884 }
885
886 #[doc = $native_doc]
887 #[repr(transparent)]
888 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
889
890 impl $native {
891 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000892 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 +0000893 let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability);
Janis Danisevskis1323d512021-11-09 07:48:08 -0800894 #[cfg(not(android_vndk))]
Stephen Cranef2735b42022-01-19 17:49:46 +0000895 $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800896 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700897 }
898 }
899
Stephen Cranef2735b42022-01-19 17:49:46 +0000900 impl $crate::binder_impl::Remotable for $native {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700901 fn get_descriptor() -> &'static str {
902 $descriptor
903 }
904
Stephen Cranef2735b42022-01-19 17:49:46 +0000905 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 -0700906 match $on_transact(&*self.0, code, data, reply) {
907 // The C++ backend converts UNEXPECTED_NULL into an exception
908 Err($crate::StatusCode::UNEXPECTED_NULL) => {
909 let status = $crate::Status::new_exception(
910 $crate::ExceptionCode::NULL_POINTER,
911 None,
912 );
913 reply.write(&status)
914 },
915 result => result
916 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700917 }
918
Stephen Cranef2735b42022-01-19 17:49:46 +0000919 fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700920 self.0.dump(file, args)
921 }
922
Stephen Cranef2735b42022-01-19 17:49:46 +0000923 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700924 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000925 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700926
927 CLASS_INIT.call_once(|| unsafe {
928 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
929 // variable, and therefore is thread-safe, as it can only occur
930 // once.
Stephen Cranef2735b42022-01-19 17:49:46 +0000931 CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700932 });
933 unsafe {
934 // Safety: The `CLASS` variable can only be mutated once, above,
935 // and is subsequently safe to read from any thread.
936 CLASS.unwrap()
937 }
938 }
939 }
940
941 impl $crate::FromIBinder for dyn $interface {
Stephen Cranef2735b42022-01-19 17:49:46 +0000942 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> {
943 use $crate::binder_impl::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700944
945 let existing_class = ibinder.get_class();
946 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +0000947 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
948 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Stephen Crane669deb62020-09-10 17:31:39 -0700949 {
950 // The binder object's descriptor string matches what we
951 // expect. We still need to treat this local or already
952 // associated object as remote, because we can't cast it
953 // into a Rust service object without a matching class
954 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +0000955 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700956 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700957 }
958
Stephen Cranef2735b42022-01-19 17:49:46 +0000959 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
960 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Stephen Crane669deb62020-09-10 17:31:39 -0700961 std::convert::TryFrom::try_from(ibinder.clone());
962 if let Ok(service) = service {
963 // We were able to associate with our expected class and
964 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800965 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700966 } else {
967 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +0000968 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700969 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000970 }
Stephen Crane669deb62020-09-10 17:31:39 -0700971
972 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700973 }
974 }
975
Stephen Cranef2735b42022-01-19 17:49:46 +0000976 impl $crate::binder_impl::Serialize for dyn $interface + '_
Stephen Crane2a3c2502020-06-16 17:48:35 -0700977 where
Stephen Craned58bce02020-07-07 12:26:02 -0700978 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700979 {
Stephen Cranef2735b42022-01-19 17:49:46 +0000980 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700981 let binder = $crate::Interface::as_binder(self);
982 parcel.write(&binder)
983 }
984 }
985
Stephen Cranef2735b42022-01-19 17:49:46 +0000986 impl $crate::binder_impl::SerializeOption for dyn $interface + '_ {
987 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700988 parcel.write(&this.map($crate::Interface::as_binder))
989 }
990 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700991
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000992 impl std::fmt::Debug for dyn $interface + '_ {
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700993 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
994 f.pad(stringify!($interface))
995 }
996 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700997
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800998 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700999 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001000 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -07001001 fn to_owned(&self) -> Self::Owned {
1002 self.as_binder().into_interface()
1003 .expect(concat!("Error cloning interface ", stringify!($interface)))
1004 }
1005 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001006
1007 $(
1008 // Async interface trait implementations.
1009 impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
Stephen Cranef2735b42022-01-19 17:49:46 +00001010 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
1011 use $crate::binder_impl::AssociateClass;
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001012
1013 let existing_class = ibinder.get_class();
1014 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +00001015 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
1016 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001017 {
1018 // The binder object's descriptor string matches what we
1019 // expect. We still need to treat this local or already
1020 // associated object as remote, because we can't cast it
1021 // into a Rust service object without a matching class
1022 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +00001023 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001024 }
1025 }
1026
Stephen Cranef2735b42022-01-19 17:49:46 +00001027 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
1028 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001029 std::convert::TryFrom::try_from(ibinder.clone());
1030 if let Ok(service) = service {
1031 // We were able to associate with our expected class and
1032 // the service is local.
1033 todo!()
1034 //return Ok($crate::Strong::new(Box::new(service)));
1035 } else {
1036 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +00001037 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001038 }
1039 }
1040
1041 Err($crate::StatusCode::BAD_TYPE.into())
1042 }
1043 }
1044
Stephen Cranef2735b42022-01-19 17:49:46 +00001045 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
1046 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001047 let binder = $crate::Interface::as_binder(self);
1048 parcel.write(&binder)
1049 }
1050 }
1051
Stephen Cranef2735b42022-01-19 17:49:46 +00001052 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
1053 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001054 parcel.write(&this.map($crate::Interface::as_binder))
1055 }
1056 }
1057
1058 impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
1059 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1060 f.pad(stringify!($async_interface))
1061 }
1062 }
1063
1064 /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
1065 impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> {
1066 type Owned = $crate::Strong<dyn $async_interface<P>>;
1067 fn to_owned(&self) -> Self::Owned {
1068 self.as_binder().into_interface()
1069 .expect(concat!("Error cloning interface ", stringify!($async_interface)))
1070 }
1071 }
Alice Ryhlc1736842021-11-23 12:38:51 +00001072
Stephen Cranef2735b42022-01-19 17:49:46 +00001073 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
Alice Ryhlc1736842021-11-23 12:38:51 +00001074 type Target = dyn $async_interface<P>;
1075 }
1076
Stephen Cranef2735b42022-01-19 17:49:46 +00001077 impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
Alice Ryhlc1736842021-11-23 12:38:51 +00001078 type Target = dyn $interface;
1079 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001080 )?
Stephen Crane2a3c2502020-06-16 17:48:35 -07001081 };
1082}
Andrei Homescu00eca712020-09-09 18:57:40 -07001083
1084/// Declare an AIDL enumeration.
1085///
1086/// This is mainly used internally by the AIDL compiler.
1087#[macro_export]
1088macro_rules! declare_binder_enum {
1089 {
Stephen Crane7bca1052021-10-25 17:52:51 -07001090 $( #[$attr:meta] )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001091 $enum:ident : [$backing:ty; $size:expr] {
Jooyung Han70d92812022-03-18 15:29:54 +09001092 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001093 }
1094 } => {
Stephen Crane7bca1052021-10-25 17:52:51 -07001095 $( #[$attr] )*
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001096 #[derive(Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001097 #[allow(missing_docs)]
Andrei Homescu00eca712020-09-09 18:57:40 -07001098 pub struct $enum(pub $backing);
1099 impl $enum {
Jooyung Han70d92812022-03-18 15:29:54 +09001100 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001101
1102 #[inline(always)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001103 #[allow(missing_docs)]
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001104 pub const fn enum_values() -> [Self; $size] {
1105 [$(Self::$name),*]
1106 }
Andrei Homescu00eca712020-09-09 18:57:40 -07001107 }
1108
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001109 impl std::fmt::Debug for $enum {
1110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1111 match self.0 {
1112 $($value => f.write_str(stringify!($name)),)*
1113 _ => f.write_fmt(format_args!("{}", self.0))
1114 }
1115 }
1116 }
1117
Stephen Cranef2735b42022-01-19 17:49:46 +00001118 impl $crate::binder_impl::Serialize for $enum {
1119 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001120 parcel.write(&self.0)
1121 }
1122 }
1123
Stephen Cranef2735b42022-01-19 17:49:46 +00001124 impl $crate::binder_impl::SerializeArray for $enum {
1125 fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001126 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
Stephen Cranef2735b42022-01-19 17:49:46 +00001127 <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel)
Andrei Homescu00eca712020-09-09 18:57:40 -07001128 }
1129 }
1130
Stephen Cranef2735b42022-01-19 17:49:46 +00001131 impl $crate::binder_impl::Deserialize for $enum {
Andrei Homescu2b802f72023-05-05 03:21:43 +00001132 type UninitType = Self;
1133 fn uninit() -> Self::UninitType { Self::UninitType::default() }
1134 fn from_init(value: Self) -> Self::UninitType { value }
1135
Stephen Cranef2735b42022-01-19 17:49:46 +00001136 fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001137 parcel.read().map(Self)
1138 }
1139 }
1140
Stephen Cranef2735b42022-01-19 17:49:46 +00001141 impl $crate::binder_impl::DeserializeArray for $enum {
1142 fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001143 let v: Option<Vec<$backing>> =
Stephen Cranef2735b42022-01-19 17:49:46 +00001144 <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?;
Andrei Homescu00eca712020-09-09 18:57:40 -07001145 Ok(v.map(|v| v.into_iter().map(Self).collect()))
1146 }
1147 }
1148 };
1149}