blob: 8c0501ba2f9098cf48f6a99cc6fa2066f3118a4e [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
Orlando Arbildod0880e82023-10-09 17:36:17 +000024use downcast_rs::{impl_downcast, DowncastSync};
Stephen Craneddb3e6d2020-12-18 13:27:22 -080025use std::borrow::Borrow;
26use std::cmp::Ordering;
Andrei Homescuee132fa2021-09-03 02:36:17 +000027use std::convert::TryFrom;
Stephen Crane669deb62020-09-10 17:31:39 -070028use std::ffi::{c_void, CStr, CString};
Stephen Craneddb3e6d2020-12-18 13:27:22 -080029use std::fmt;
Andrei Homescud23c0492023-11-09 01:51:59 +000030use std::io::Write;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080031use std::marker::PhantomData;
32use std::ops::Deref;
Andrei Homescu4b21b9f2023-05-09 02:50:37 +000033use std::os::fd::AsRawFd;
Stephen Crane669deb62020-09-10 17:31:39 -070034use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070035use std::ptr;
36
37/// Binder action to perform.
38///
Andrew Walbran12400d82021-03-04 17:04:34 +000039/// This must be a number between [`FIRST_CALL_TRANSACTION`] and
40/// [`LAST_CALL_TRANSACTION`].
Stephen Crane2a3c2502020-06-16 17:48:35 -070041pub type TransactionCode = u32;
42
43/// Additional operation flags.
44///
Andrew Walbran12400d82021-03-04 17:04:34 +000045/// `FLAG_*` values.
Stephen Crane2a3c2502020-06-16 17:48:35 -070046pub type TransactionFlags = u32;
47
48/// Super-trait for Binder interfaces.
49///
50/// This trait allows conversion of a Binder interface trait object into an
51/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
52/// interfaces) must implement this trait.
53///
54/// This is equivalent `IInterface` in C++.
Orlando Arbildod0880e82023-10-09 17:36:17 +000055pub trait Interface: Send + Sync + DowncastSync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070056 /// Convert this binder object into a generic [`SpIBinder`] reference.
57 fn as_binder(&self) -> SpIBinder {
58 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
59 }
Stephen Crane2a3297f2021-06-11 16:48:10 -070060
61 /// Dump transaction handler for this Binder object.
62 ///
63 /// This handler is a no-op by default and should be implemented for each
64 /// Binder service struct that wishes to respond to dump transactions.
Andrei Homescud23c0492023-11-09 01:51:59 +000065 fn dump(&self, _writer: &mut dyn Write, _args: &[&CStr]) -> Result<()> {
Stephen Crane2a3297f2021-06-11 16:48:10 -070066 Ok(())
67 }
Stephen Crane2a3c2502020-06-16 17:48:35 -070068}
69
Orlando Arbildod0880e82023-10-09 17:36:17 +000070impl_downcast!(sync Interface);
71
Alice Ryhlc1736842021-11-23 12:38:51 +000072/// Implemented by sync interfaces to specify what the associated async interface is.
73/// Generic to handle the fact that async interfaces are generic over a thread pool.
74///
75/// The binder in any object implementing this trait should be compatible with the
76/// `Target` associated type, and using `FromIBinder` to convert it to the target
77/// should not fail.
78pub trait ToAsyncInterface<P>
79where
80 Self: Interface,
81 Self::Target: FromIBinder,
82{
83 /// The async interface associated with this sync interface.
84 type Target: ?Sized;
85}
86
87/// Implemented by async interfaces to specify what the associated sync interface is.
88///
89/// The binder in any object implementing this trait should be compatible with the
90/// `Target` associated type, and using `FromIBinder` to convert it to the target
91/// should not fail.
92pub trait ToSyncInterface
93where
94 Self: Interface,
95 Self::Target: FromIBinder,
96{
97 /// The sync interface associated with this async interface.
98 type Target: ?Sized;
99}
100
Stephen Craneff7f03a2021-02-25 16:04:22 -0800101/// Interface stability promise
102///
Andrei Homescu3e9c13a2023-05-09 02:48:22 +0000103/// An interface can promise to be a stable vendor interface ([`Stability::Vintf`]),
104/// or makes no stability guarantees ([`Stability::Local`]). [`Stability::Local`] is
Stephen Craneff7f03a2021-02-25 16:04:22 -0800105/// currently the default stability.
Chariseeab53d0a2023-03-03 02:08:34 +0000106#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800107pub enum Stability {
108 /// Default stability, visible to other modules in the same compilation
109 /// context (e.g. modules on system.img)
Chariseeab53d0a2023-03-03 02:08:34 +0000110 #[default]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800111 Local,
112
113 /// A Vendor Interface Object, which promises to be stable
114 Vintf,
115}
116
Andrei Homescuee132fa2021-09-03 02:36:17 +0000117impl From<Stability> for i32 {
118 fn from(stability: Stability) -> i32 {
119 use Stability::*;
120 match stability {
121 Local => 0,
122 Vintf => 1,
123 }
124 }
125}
126
127impl TryFrom<i32> for Stability {
128 type Error = StatusCode;
129 fn try_from(stability: i32) -> Result<Stability> {
130 use Stability::*;
131 match stability {
132 0 => Ok(Local),
133 1 => Ok(Vintf),
Matthew Maurere268a9f2022-07-26 09:31:30 -0700134 _ => Err(StatusCode::BAD_VALUE),
Andrei Homescuee132fa2021-09-03 02:36:17 +0000135 }
136 }
137}
138
Frederick Maylee2543232024-09-16 21:05:49 -0700139/// Same as `Stability`, but in the form of a trait. Used when the stability should be encoded in
140/// the type.
141///
142/// When/if the `adt_const_params` Rust feature is stabilized, this could be replace by using
143/// `Stability` directly with const generics.
144pub trait StabilityType {
145 /// The `Stability` represented by this type.
146 const VALUE: Stability;
147}
148
149/// `Stability::Local`.
150#[derive(Debug)]
151pub enum LocalStabilityType {}
152/// `Stability::Vintf`.
153#[derive(Debug)]
154pub enum VintfStabilityType {}
155
156impl StabilityType for LocalStabilityType {
157 const VALUE: Stability = Stability::Local;
158}
159
160impl StabilityType for VintfStabilityType {
161 const VALUE: Stability = Stability::Vintf;
162}
163
Stephen Crane2a3c2502020-06-16 17:48:35 -0700164/// A local service that can be remotable via Binder.
165///
166/// An object that implement this interface made be made into a Binder service
167/// via `Binder::new(object)`.
168///
169/// This is a low-level interface that should normally be automatically
Andrei Homescu3e9c13a2023-05-09 02:48:22 +0000170/// generated from AIDL via the [`crate::declare_binder_interface!`] macro.
171/// When using the AIDL backend, users need only implement the high-level AIDL-defined
Stephen Crane2a3c2502020-06-16 17:48:35 -0700172/// interface. The AIDL compiler then generates a container struct that wraps
173/// the user-defined service and implements `Remotable`.
Orlando Arbildod0880e82023-10-09 17:36:17 +0000174pub trait Remotable: Send + Sync + 'static {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700175 /// The Binder interface descriptor string.
176 ///
177 /// This string is a unique identifier for a Binder interface, and should be
178 /// the same between all implementations of that interface.
179 fn get_descriptor() -> &'static str;
180
181 /// Handle and reply to a request to invoke a transaction on this object.
182 ///
183 /// `reply` may be [`None`] if the sender does not expect a reply.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700184 fn on_transact(
185 &self,
186 code: TransactionCode,
187 data: &BorrowedParcel<'_>,
188 reply: &mut BorrowedParcel<'_>,
189 ) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700190
Stephen Crane2a3297f2021-06-11 16:48:10 -0700191 /// Handle a request to invoke the dump transaction on this
192 /// object.
Andrei Homescud23c0492023-11-09 01:51:59 +0000193 fn on_dump(&self, file: &mut dyn Write, args: &[&CStr]) -> Result<()>;
Stephen Crane2a3297f2021-06-11 16:48:10 -0700194
Stephen Crane2a3c2502020-06-16 17:48:35 -0700195 /// Retrieve the class of this remote object.
196 ///
197 /// This method should always return the same InterfaceClass for the same
198 /// type.
199 fn get_class() -> InterfaceClass;
200}
201
Andrew Walbran12400d82021-03-04 17:04:34 +0000202/// First transaction code available for user commands (inclusive)
203pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
204/// Last transaction code available for user commands (inclusive)
205pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
206
207/// Corresponds to TF_ONE_WAY -- an asynchronous call.
208pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
209/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
Matthew Maurer75d71122024-10-09 22:20:41 +0000210#[cfg(not(android_ndk))]
Andrew Walbran12400d82021-03-04 17:04:34 +0000211pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800212/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
Matthew Maurer75d71122024-10-09 22:20:41 +0000213#[cfg(not(android_ndk))]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800214pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000215
216/// Internal interface of binder local or remote objects for making
217/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700218///
Andrew Walbran12400d82021-03-04 17:04:34 +0000219/// This trait corresponds to the parts of the interface of the C++ `IBinder`
220/// class which are internal implementation details.
221pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700222 /// Is this object still alive?
223 fn is_binder_alive(&self) -> bool;
224
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700225 /// Indicate that the service intends to receive caller security contexts.
Matthew Maurer75d71122024-10-09 22:20:41 +0000226 #[cfg(not(any(android_vndk, android_ndk)))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700227 fn set_requesting_sid(&mut self, enable: bool);
228
Stephen Crane2a3c2502020-06-16 17:48:35 -0700229 /// Dump this object to the given file handle
230 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
231
232 /// Get a new interface that exposes additional extension functionality, if
233 /// available.
234 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
235
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000236 /// Create a Parcel that can be used with `submit_transact`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000237 fn prepare_transact(&self) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000238
Stephen Crane2a3c2502020-06-16 17:48:35 -0700239 /// Perform a generic operation with the object.
240 ///
Alice Ryhl8618c482021-11-09 15:35:35 +0000241 /// The provided [`Parcel`] must have been created by a call to
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000242 /// `prepare_transact` on the same binder.
243 ///
244 /// # Arguments
245 ///
246 /// * `code` - Transaction code for the operation.
Alice Ryhl8618c482021-11-09 15:35:35 +0000247 /// * `data` - [`Parcel`] with input data.
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000248 /// * `flags` - Transaction flags, e.g. marking the transaction as
249 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
250 fn submit_transact(
251 &self,
252 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000253 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000254 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000255 ) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000256
257 /// Perform a generic operation with the object. This is a convenience
258 /// method that internally calls `prepare_transact` followed by
259 /// `submit_transact.
260 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700261 /// # Arguments
262 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700263 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000264 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000265 /// * `input_callback` A callback for building the `Parcel`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000266 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
Stephen Crane2a3c2502020-06-16 17:48:35 -0700267 &self,
268 code: TransactionCode,
269 flags: TransactionFlags,
270 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000271 ) -> Result<Parcel> {
272 let mut parcel = self.prepare_transact()?;
Alice Ryhl8618c482021-11-09 15:35:35 +0000273 input_callback(parcel.borrowed())?;
274 self.submit_transact(code, parcel, flags)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000275 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000276}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700277
Andrew Walbran12400d82021-03-04 17:04:34 +0000278/// Interface of binder local or remote objects.
279///
280/// This trait corresponds to the parts of the interface of the C++ `IBinder`
281/// class which are public.
282pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700283 /// Register the recipient for a notification if this binder
284 /// goes away. If this binder object unexpectedly goes away
285 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000286 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700287 ///
288 /// You will only receive death notifications for remote binders,
289 /// as local binders by definition can't die without you dying as well.
290 /// Trying to use this function on a local binder will result in an
291 /// INVALID_OPERATION code being returned and nothing happening.
292 ///
Andrew Walbranfee58632023-06-22 17:36:48 +0000293 /// This link only holds a weak reference to its recipient. If the
294 /// `DeathRecipient` is dropped then it will be unlinked.
295 ///
296 /// Note that the notifications won't work if you don't first start at least
297 /// one Binder thread by calling
298 /// [`ProcessState::start_thread_pool`](crate::ProcessState::start_thread_pool)
299 /// or
300 /// [`ProcessState::join_thread_pool`](crate::ProcessState::join_thread_pool).
Stephen Crane2a3c2502020-06-16 17:48:35 -0700301 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
302
303 /// Remove a previously registered death notification.
304 /// The recipient will no longer be called if this object
305 /// dies.
306 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
Stephen Crane61366d42022-01-20 17:45:34 -0800307
308 /// Send a ping transaction to this object
309 fn ping_binder(&mut self) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700310}
311
312/// Opaque reference to the type of a Binder interface.
313///
314/// This object encapsulates the Binder interface descriptor string, along with
315/// the binder transaction callback, if the class describes a local service.
316///
317/// A Binder remotable object may only have a single interface class, and any
318/// given object can only be associated with one class. Two objects with
319/// different classes are incompatible, even if both classes have the same
320/// interface descriptor.
321#[derive(Copy, Clone, PartialEq, Eq)]
322pub struct InterfaceClass(*const sys::AIBinder_Class);
323
324impl InterfaceClass {
325 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
326 ///
327 /// Note: the returned pointer will not be constant. Calling this method
328 /// multiple times for the same type will result in distinct class
329 /// pointers. A static getter for this value is implemented in
Andrei Homescu3e9c13a2023-05-09 02:48:22 +0000330 /// [`crate::declare_binder_interface!`].
Stephen Crane2a3c2502020-06-16 17:48:35 -0700331 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
332 let descriptor = CString::new(I::get_descriptor()).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100333 // Safety: `AIBinder_Class_define` expects a valid C string, and three
334 // valid callback functions, all non-null pointers. The C string is
335 // copied and need not be valid for longer than the call, so we can drop
336 // it after the call. We can safely assign null to the onDump and
337 // handleShellCommand callbacks as long as the class pointer was
338 // non-null. Rust None for a Option<fn> is guaranteed to be a NULL
339 // pointer. Rust retains ownership of the pointer after it is defined.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700340 let ptr = unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700341 let class = sys::AIBinder_Class_define(
342 descriptor.as_ptr(),
343 Some(I::on_create),
344 Some(I::on_destroy),
345 Some(I::on_transact),
346 );
347 if class.is_null() {
348 panic!("Expected non-null class pointer from AIBinder_Class_define!");
349 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700350 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700351 class
352 };
353 InterfaceClass(ptr)
354 }
355
356 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
357 /// pointer.
358 ///
359 /// # Safety
360 ///
361 /// This function is safe iff `ptr` is a valid, non-null pointer to an
362 /// `AIBinder_Class`.
363 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
364 InterfaceClass(ptr)
365 }
Stephen Crane669deb62020-09-10 17:31:39 -0700366
367 /// Get the interface descriptor string of this class.
368 pub fn get_descriptor(&self) -> String {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100369 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor is
370 // always a two-byte null terminated sequence of u16s. Thus, we can
371 // continue reading from the pointer until we hit a null value, and this
372 // pointer can be a valid slice if the slice length is <= the number of
373 // u16 elements before the null terminator.
Stephen Crane669deb62020-09-10 17:31:39 -0700374 unsafe {
Stephen Crane669deb62020-09-10 17:31:39 -0700375 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000376 CStr::from_ptr(raw_descriptor)
377 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700378 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
379 .into()
380 }
381 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700382}
383
384impl From<InterfaceClass> for *const sys::AIBinder_Class {
385 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
386 class.0
387 }
388}
389
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800390/// Strong reference to a binder object
391pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
392
393impl<I: FromIBinder + ?Sized> Strong<I> {
394 /// Create a new strong reference to the provided binder object
395 pub fn new(binder: Box<I>) -> Self {
396 Self(binder)
397 }
398
399 /// Construct a new weak reference to this binder
400 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
401 Weak::new(this)
402 }
Alice Ryhlc1736842021-11-23 12:38:51 +0000403
404 /// Convert this synchronous binder handle into an asynchronous one.
405 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
406 where
407 I: ToAsyncInterface<P>,
408 {
409 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder
410 // object is also valid for the target type.
411 FromIBinder::try_from(self.0.as_binder()).unwrap()
412 }
413
414 /// Convert this asynchronous binder handle into a synchronous one.
415 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
416 where
417 I: ToSyncInterface,
418 {
419 // By implementing the ToSyncInterface trait, it is guaranteed that the binder
420 // object is also valid for the target type.
421 FromIBinder::try_from(self.0.as_binder()).unwrap()
422 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800423}
424
425impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
426 fn clone(&self) -> Self {
427 // Since we hold a strong reference, we should always be able to create
428 // a new strong reference to the same interface type, so try_from()
429 // should never fail here.
430 FromIBinder::try_from(self.0.as_binder()).unwrap()
431 }
432}
433
434impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
435 fn borrow(&self) -> &I {
436 &self.0
437 }
438}
439
440impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
441 fn as_ref(&self) -> &I {
442 &self.0
443 }
444}
445
446impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
447 type Target = I;
448
449 fn deref(&self) -> &Self::Target {
450 &self.0
451 }
452}
453
454impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
455 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
456 fmt::Debug::fmt(&**self, f)
457 }
458}
459
460impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
461 fn cmp(&self, other: &Self) -> Ordering {
462 self.0.as_binder().cmp(&other.0.as_binder())
463 }
464}
465
466impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
467 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Charisee Chiwad1b27c2023-10-12 16:02:39 -0700468 Some(self.cmp(other))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800469 }
470}
471
472impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
473 fn eq(&self, other: &Self) -> bool {
474 self.0.as_binder().eq(&other.0.as_binder())
475 }
476}
477
478impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
479
480/// Weak reference to a binder object
481#[derive(Debug)]
482pub struct Weak<I: FromIBinder + ?Sized> {
483 weak_binder: WpIBinder,
484 interface_type: PhantomData<I>,
485}
486
487impl<I: FromIBinder + ?Sized> Weak<I> {
488 /// Construct a new weak reference from a strong reference
489 fn new(binder: &Strong<I>) -> Self {
490 let weak_binder = binder.as_binder().downgrade();
Matthew Maurere268a9f2022-07-26 09:31:30 -0700491 Weak { weak_binder, interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800492 }
493
494 /// Upgrade this weak reference to a strong reference if the binder object
495 /// is still alive
496 pub fn upgrade(&self) -> Result<Strong<I>> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700497 self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from)
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800498 }
499}
500
501impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
502 fn clone(&self) -> Self {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700503 Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800504 }
505}
506
507impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
508 fn cmp(&self, other: &Self) -> Ordering {
509 self.weak_binder.cmp(&other.weak_binder)
510 }
511}
512
513impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
514 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Charisee Chiwad1b27c2023-10-12 16:02:39 -0700515 Some(self.cmp(other))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800516 }
517}
518
519impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
520 fn eq(&self, other: &Self) -> bool {
521 self.weak_binder == other.weak_binder
522 }
523}
524
525impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
526
Stephen Crane2a3c2502020-06-16 17:48:35 -0700527/// Create a function implementing a static getter for an interface class.
528///
529/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
530/// [`Interface`]) must have global, static class that uniquely identifies
531/// it. This macro implements an [`InterfaceClass`] getter to simplify these
532/// implementations.
533///
534/// The type of a structure that implements [`InterfaceClassMethods`] must be
535/// passed to this macro. For local services, this should be `Binder<Self>`
536/// since [`Binder`] implements [`InterfaceClassMethods`].
537///
538/// # Examples
539///
540/// When implementing a local [`Remotable`] service `ExampleService`, the
541/// `get_class` method is required in the [`Remotable`] impl block. This macro
542/// should be used as follows to implement this functionality:
543///
544/// ```rust
545/// impl Remotable for ExampleService {
546/// fn get_descriptor() -> &'static str {
547/// "android.os.IExampleInterface"
548/// }
549///
550/// fn on_transact(
551/// &self,
552/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000553/// data: &BorrowedParcel,
554/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700555/// ) -> Result<()> {
556/// // ...
557/// }
558///
559/// binder_fn_get_class!(Binder<Self>);
560/// }
561/// ```
562macro_rules! binder_fn_get_class {
563 ($class:ty) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000564 binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700565 };
566
567 ($constructor:expr) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000568 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700569 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000570 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700571
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100572 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
573 // variable, and therefore is thread-safe, as it can only occur
574 // once.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700575 CLASS_INIT.call_once(|| unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700576 CLASS = Some($constructor);
577 });
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100578 // Safety: The `CLASS` variable can only be mutated once, above, and
579 // is subsequently safe to read from any thread.
580 unsafe { CLASS.unwrap() }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700581 }
582 };
583}
584
585pub trait InterfaceClassMethods {
586 /// Get the interface descriptor string for this object type.
587 fn get_descriptor() -> &'static str
588 where
589 Self: Sized;
590
591 /// Called during construction of a new `AIBinder` object of this interface
592 /// class.
593 ///
594 /// The opaque pointer parameter will be the parameter provided to
595 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
596 /// `AIBinder` object.
597 ///
598 /// # Safety
599 ///
600 /// Callback called from C++. The parameter argument provided to
601 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
602 /// will take ownership of the returned pointer, which it will free via
603 /// `on_destroy`.
604 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
605
606 /// Called when a transaction needs to be processed by the local service
607 /// implementation.
608 ///
609 /// # Safety
610 ///
611 /// Callback called from C++. The `binder` parameter must be a valid pointer
612 /// to a binder object of this class with userdata initialized via this
613 /// class's `on_create`. The parcel parameters must be valid pointers to
614 /// parcel objects.
615 unsafe extern "C" fn on_transact(
616 binder: *mut sys::AIBinder,
617 code: u32,
618 data: *const sys::AParcel,
619 reply: *mut sys::AParcel,
620 ) -> status_t;
621
622 /// Called whenever an `AIBinder` object is no longer referenced and needs
623 /// to be destroyed.
624 ///
625 /// # Safety
626 ///
627 /// Callback called from C++. The opaque pointer parameter must be the value
628 /// returned by `on_create` for this class. This function takes ownership of
629 /// the provided pointer and destroys it.
630 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700631
632 /// Called to handle the `dump` transaction.
633 ///
634 /// # Safety
635 ///
636 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
637 /// contains a `T` pointer in its user data. fd should be a non-owned file
638 /// descriptor, and args must be an array of null-terminated string
639 /// poiinters with length num_args.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700640 unsafe extern "C" fn on_dump(
641 binder: *mut sys::AIBinder,
642 fd: i32,
643 args: *mut *const c_char,
644 num_args: u32,
645 ) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700646}
647
648/// Interface for transforming a generic SpIBinder into a specific remote
649/// interface trait.
650///
651/// # Example
652///
653/// For Binder interface `IFoo`, the following implementation should be made:
654/// ```no_run
655/// # use binder::{FromIBinder, SpIBinder, Result};
656/// # trait IFoo {}
657/// impl FromIBinder for dyn IFoo {
658/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
659/// // ...
660/// # Err(binder::StatusCode::OK)
661/// }
662/// }
663/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800664pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700665 /// Try to interpret a generic Binder object as this interface.
666 ///
667 /// Returns a trait object for the `Self` interface if this object
668 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800669 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700670}
671
672/// Trait for transparent Rust wrappers around android C++ native types.
673///
674/// The pointer return by this trait's methods should be immediately passed to
675/// C++ and not stored by Rust. The pointer is valid only as long as the
676/// underlying C++ object is alive, so users must be careful to take this into
677/// account, as Rust cannot enforce this.
678///
679/// # Safety
680///
681/// For this trait to be a correct implementation, `T` must be a valid android
682/// C++ type. Since we cannot constrain this via the type system, this trait is
683/// marked as unsafe.
684pub unsafe trait AsNative<T> {
685 /// Return a pointer to the native version of `self`
686 fn as_native(&self) -> *const T;
687
688 /// Return a mutable pointer to the native version of `self`
689 fn as_native_mut(&mut self) -> *mut T;
690}
691
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100692// Safety: If V is a valid Android C++ type then we can either use that or a
693// null pointer.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700694unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
695 fn as_native(&self) -> *const T {
696 self.as_ref().map_or(ptr::null(), |v| v.as_native())
697 }
698
699 fn as_native_mut(&mut self) -> *mut T {
700 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
701 }
702}
703
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000704/// The features to enable when creating a native Binder.
705///
706/// This should always be initialised with a default value, e.g.:
707/// ```
708/// # use binder::BinderFeatures;
709/// BinderFeatures {
710/// set_requesting_sid: true,
711/// ..BinderFeatures::default(),
712/// }
713/// ```
714#[derive(Clone, Debug, Default, Eq, PartialEq)]
715pub struct BinderFeatures {
716 /// Indicates that the service intends to receive caller security contexts. This must be true
717 /// for `ThreadState::with_calling_sid` to work.
Matthew Maurer75d71122024-10-09 22:20:41 +0000718 #[cfg(not(any(android_vndk, android_ndk)))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000719 pub set_requesting_sid: bool,
720 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
721 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
722 // expressions entirely.
723 #[doc(hidden)]
724 pub _non_exhaustive: (),
725}
726
Stephen Crane2a3c2502020-06-16 17:48:35 -0700727/// Declare typed interfaces for a binder object.
728///
729/// Given an interface trait and descriptor string, create a native and remote
730/// proxy wrapper for this interface. The native service object (`$native`)
731/// implements `Remotable` and will dispatch to the function `$on_transact` to
732/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
733/// objects for this interface and can optionally contain additional fields.
734///
735/// Assuming the interface trait is `Interface`, `$on_transact` function must
736/// have the following type:
737///
738/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000739/// # use binder::{Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700740/// # trait Placeholder {
741/// fn on_transact(
742/// service: &dyn Interface,
743/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000744/// data: &BorrowedParcel,
745/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700746/// ) -> binder::Result<()>;
747/// # }
748/// ```
749///
750/// # Examples
751///
752/// The following example declares the local service type `BnServiceManager` and
753/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
754/// proxy respectively) for the `IServiceManager` Binder interface. The
755/// interfaces will be identified by the descriptor string
756/// "android.os.IServiceManager". The local service will dispatch transactions
757/// using the provided function, `on_transact`.
758///
759/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000760/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700761///
762/// pub trait IServiceManager: Interface {
763/// // remote methods...
764/// }
765///
766/// declare_binder_interface! {
767/// IServiceManager["android.os.IServiceManager"] {
768/// native: BnServiceManager(on_transact),
769/// proxy: BpServiceManager,
770/// }
771/// }
772///
773/// fn on_transact(
774/// service: &dyn IServiceManager,
775/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000776/// data: &BorrowedParcel,
777/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700778/// ) -> binder::Result<()> {
779/// // ...
780/// Ok(())
781/// }
782///
783/// impl IServiceManager for BpServiceManager {
784/// // parceling/unparceling code for the IServiceManager emitted here
785/// }
786///
787/// impl IServiceManager for Binder<BnServiceManager> {
788/// // Forward calls to local implementation
789/// }
790/// ```
791#[macro_export]
792macro_rules! declare_binder_interface {
793 {
794 $interface:path[$descriptor:expr] {
795 native: $native:ident($on_transact:path),
796 proxy: $proxy:ident,
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000797 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700798 }
799 } => {
800 $crate::declare_binder_interface! {
801 $interface[$descriptor] {
802 native: $native($on_transact),
803 proxy: $proxy {},
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000804 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000805 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800806 }
807 }
808 };
809
810 {
811 $interface:path[$descriptor:expr] {
812 native: $native:ident($on_transact:path),
813 proxy: $proxy:ident,
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000814 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800815 stability: $stability:expr,
816 }
817 } => {
818 $crate::declare_binder_interface! {
819 $interface[$descriptor] {
820 native: $native($on_transact),
821 proxy: $proxy {},
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000822 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800823 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700824 }
825 }
826 };
827
828 {
829 $interface:path[$descriptor:expr] {
830 native: $native:ident($on_transact:path),
831 proxy: $proxy:ident {
832 $($fname:ident: $fty:ty = $finit:expr),*
833 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000834 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700835 }
836 } => {
837 $crate::declare_binder_interface! {
838 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800839 native: $native($on_transact),
840 proxy: $proxy {
841 $($fname: $fty = $finit),*
842 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000843 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000844 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800845 }
846 }
847 };
848
849 {
850 $interface:path[$descriptor:expr] {
851 native: $native:ident($on_transact:path),
852 proxy: $proxy:ident {
853 $($fname:ident: $fty:ty = $finit:expr),*
854 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000855 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800856 stability: $stability:expr,
857 }
858 } => {
859 $crate::declare_binder_interface! {
860 $interface[$descriptor] {
Stephen Cranef2735b42022-01-19 17:49:46 +0000861 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700862 native: $native($on_transact),
Stephen Cranef2735b42022-01-19 17:49:46 +0000863 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700864 proxy: $proxy {
865 $($fname: $fty = $finit),*
866 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000867 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800868 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700869 }
870 }
871 };
872
873 {
874 $interface:path[$descriptor:expr] {
875 @doc[$native_doc:expr]
876 native: $native:ident($on_transact:path),
877
878 @doc[$proxy_doc:expr]
879 proxy: $proxy:ident {
880 $($fname:ident: $fty:ty = $finit:expr),*
881 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800882
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000883 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000884
Stephen Craneff7f03a2021-02-25 16:04:22 -0800885 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700886 }
887 } => {
888 #[doc = $proxy_doc]
889 pub struct $proxy {
890 binder: $crate::SpIBinder,
891 $($fname: $fty,)*
892 }
893
894 impl $crate::Interface for $proxy {
895 fn as_binder(&self) -> $crate::SpIBinder {
896 self.binder.clone()
897 }
898 }
899
Stephen Cranef2735b42022-01-19 17:49:46 +0000900 impl $crate::binder_impl::Proxy for $proxy
Stephen Crane2a3c2502020-06-16 17:48:35 -0700901 where
902 $proxy: $interface,
903 {
904 fn get_descriptor() -> &'static str {
905 $descriptor
906 }
907
Stephen Cranef2735b42022-01-19 17:49:46 +0000908 fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> {
Stephen Crane669deb62020-09-10 17:31:39 -0700909 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700910 }
911 }
912
913 #[doc = $native_doc]
914 #[repr(transparent)]
915 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
916
917 impl $native {
918 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000919 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
Matthew Maurer75d71122024-10-09 22:20:41 +0000920 #[cfg(not(android_ndk))]
Stephen Cranef2735b42022-01-19 17:49:46 +0000921 let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability);
Matthew Maurer75d71122024-10-09 22:20:41 +0000922 #[cfg(android_ndk)]
923 let mut binder = $crate::binder_impl::Binder::new($native(Box::new(inner)));
924
925 #[cfg(not(any(android_vndk, android_ndk)))]
Stephen Cranef2735b42022-01-19 17:49:46 +0000926 $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800927 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700928 }
Orlando Arbildod0880e82023-10-09 17:36:17 +0000929
930 /// Tries to downcast the interface to another type.
931 /// When receiving this object from a binder call, make sure that the object received is
932 /// a binder native object and that is of the right type for the Downcast:
933 ///
934 /// let binder = received_object.as_binder();
935 /// if !binder.is_remote() {
936 /// let binder_native: Binder<BnFoo> = binder.try_into()?;
937 /// let original_object = binder_native.downcast_binder::<MyFoo>();
938 /// // Check that returned type is not None before using it
939 /// }
940 ///
941 /// Handle the error cases instead of just calling `unwrap` or `expect` to prevent a
942 /// malicious caller to mount a Denial of Service attack.
943 pub fn downcast_binder<T: $interface>(&self) -> Option<&T> {
944 self.0.as_any().downcast_ref::<T>()
945 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700946 }
947
Stephen Cranef2735b42022-01-19 17:49:46 +0000948 impl $crate::binder_impl::Remotable for $native {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700949 fn get_descriptor() -> &'static str {
950 $descriptor
951 }
952
Stephen Cranef2735b42022-01-19 17:49:46 +0000953 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 -0700954 match $on_transact(&*self.0, code, data, reply) {
955 // The C++ backend converts UNEXPECTED_NULL into an exception
956 Err($crate::StatusCode::UNEXPECTED_NULL) => {
957 let status = $crate::Status::new_exception(
958 $crate::ExceptionCode::NULL_POINTER,
959 None,
960 );
961 reply.write(&status)
962 },
963 result => result
964 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700965 }
966
Andrei Homescud23c0492023-11-09 01:51:59 +0000967 fn on_dump(&self, writer: &mut dyn std::io::Write, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> {
968 self.0.dump(writer, args)
Stephen Crane2a3297f2021-06-11 16:48:10 -0700969 }
970
Stephen Cranef2735b42022-01-19 17:49:46 +0000971 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700972 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000973 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700974
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100975 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
976 // variable, and therefore is thread-safe, as it can only occur
977 // once.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700978 CLASS_INIT.call_once(|| unsafe {
Stephen Cranef2735b42022-01-19 17:49:46 +0000979 CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700980 });
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100981 // Safety: The `CLASS` variable can only be mutated once, above,
982 // and is subsequently safe to read from any thread.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700983 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700984 CLASS.unwrap()
985 }
986 }
987 }
988
989 impl $crate::FromIBinder for dyn $interface {
Stephen Cranef2735b42022-01-19 17:49:46 +0000990 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> {
991 use $crate::binder_impl::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700992
993 let existing_class = ibinder.get_class();
994 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +0000995 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
996 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Stephen Crane669deb62020-09-10 17:31:39 -0700997 {
998 // The binder object's descriptor string matches what we
999 // expect. We still need to treat this local or already
1000 // associated object as remote, because we can't cast it
1001 // into a Rust service object without a matching class
1002 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +00001003 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -07001004 }
Stephen Crane2a3c2502020-06-16 17:48:35 -07001005 }
1006
Stephen Cranef2735b42022-01-19 17:49:46 +00001007 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
1008 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Stephen Crane669deb62020-09-10 17:31:39 -07001009 std::convert::TryFrom::try_from(ibinder.clone());
1010 if let Ok(service) = service {
1011 // We were able to associate with our expected class and
1012 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001013 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -07001014 } else {
1015 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +00001016 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -07001017 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +00001018 }
Stephen Crane669deb62020-09-10 17:31:39 -07001019
1020 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -07001021 }
1022 }
1023
Stephen Cranef2735b42022-01-19 17:49:46 +00001024 impl $crate::binder_impl::Serialize for dyn $interface + '_
Stephen Crane2a3c2502020-06-16 17:48:35 -07001025 where
Stephen Craned58bce02020-07-07 12:26:02 -07001026 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -07001027 {
Stephen Cranef2735b42022-01-19 17:49:46 +00001028 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -07001029 let binder = $crate::Interface::as_binder(self);
1030 parcel.write(&binder)
1031 }
1032 }
1033
Stephen Cranef2735b42022-01-19 17:49:46 +00001034 impl $crate::binder_impl::SerializeOption for dyn $interface + '_ {
1035 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -07001036 parcel.write(&this.map($crate::Interface::as_binder))
1037 }
1038 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -07001039
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001040 impl std::fmt::Debug for dyn $interface + '_ {
Andrei Homescu2e3c1472020-08-11 16:35:40 -07001041 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1042 f.pad(stringify!($interface))
1043 }
1044 }
Andrei Homescu64ebd132020-08-07 22:12:48 -07001045
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001046 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -07001047 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001048 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -07001049 fn to_owned(&self) -> Self::Owned {
1050 self.as_binder().into_interface()
1051 .expect(concat!("Error cloning interface ", stringify!($interface)))
1052 }
1053 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001054
1055 $(
1056 // Async interface trait implementations.
Orlando Arbildod0880e82023-10-09 17:36:17 +00001057 impl<P: $crate::BinderAsyncPool + 'static> $crate::FromIBinder for dyn $async_interface<P> {
Stephen Cranef2735b42022-01-19 17:49:46 +00001058 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
1059 use $crate::binder_impl::AssociateClass;
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001060
1061 let existing_class = ibinder.get_class();
1062 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +00001063 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
1064 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001065 {
1066 // The binder object's descriptor string matches what we
1067 // expect. We still need to treat this local or already
1068 // associated object as remote, because we can't cast it
1069 // into a Rust service object without a matching class
1070 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +00001071 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001072 }
1073 }
1074
Stephen Cranef2735b42022-01-19 17:49:46 +00001075 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
Alice Ryhl0ae829e2024-05-21 14:21:22 +00001076 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
1077 std::convert::TryFrom::try_from(ibinder.clone());
1078 $(
1079 // This part is only generated if the user of the macro specifies that the
1080 // trait has an `try_into_local_async` implementation.
1081 if let Ok(service) = service {
1082 if let Some(async_service) = $native::$try_into_local_async(service) {
1083 // We were able to associate with our expected class,
1084 // the service is local, and the local service is async.
1085 return Ok(async_service);
1086 }
1087 // The service is local but not async. Fall back to treating it as a
1088 // remote service. This means that calls to this local service have an
1089 // extra performance cost due to serialization, but async handle to
1090 // non-async server is considered a rare case, so this is okay.
1091 }
1092 )?
1093 // Treat service as remote.
Alice Ryhleed9ac12023-07-25 13:45:47 +00001094 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001095 }
1096
1097 Err($crate::StatusCode::BAD_TYPE.into())
1098 }
1099 }
1100
Orlando Arbildod0880e82023-10-09 17:36:17 +00001101 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
Stephen Cranef2735b42022-01-19 17:49:46 +00001102 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001103 let binder = $crate::Interface::as_binder(self);
1104 parcel.write(&binder)
1105 }
1106 }
1107
Orlando Arbildod0880e82023-10-09 17:36:17 +00001108 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
Stephen Cranef2735b42022-01-19 17:49:46 +00001109 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001110 parcel.write(&this.map($crate::Interface::as_binder))
1111 }
1112 }
1113
Orlando Arbildod0880e82023-10-09 17:36:17 +00001114 impl<P: $crate::BinderAsyncPool + 'static> std::fmt::Debug for dyn $async_interface<P> + '_ {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1116 f.pad(stringify!($async_interface))
1117 }
1118 }
1119
1120 /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
Orlando Arbildod0880e82023-10-09 17:36:17 +00001121 impl<P: $crate::BinderAsyncPool + 'static> std::borrow::ToOwned for dyn $async_interface<P> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001122 type Owned = $crate::Strong<dyn $async_interface<P>>;
1123 fn to_owned(&self) -> Self::Owned {
1124 self.as_binder().into_interface()
1125 .expect(concat!("Error cloning interface ", stringify!($async_interface)))
1126 }
1127 }
Alice Ryhlc1736842021-11-23 12:38:51 +00001128
Orlando Arbildod0880e82023-10-09 17:36:17 +00001129 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
Alice Ryhlc1736842021-11-23 12:38:51 +00001130 type Target = dyn $async_interface<P>;
1131 }
1132
Orlando Arbildod0880e82023-10-09 17:36:17 +00001133 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
Alice Ryhlc1736842021-11-23 12:38:51 +00001134 type Target = dyn $interface;
1135 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001136 )?
Stephen Crane2a3c2502020-06-16 17:48:35 -07001137 };
1138}
Andrei Homescu00eca712020-09-09 18:57:40 -07001139
1140/// Declare an AIDL enumeration.
1141///
1142/// This is mainly used internally by the AIDL compiler.
1143#[macro_export]
1144macro_rules! declare_binder_enum {
1145 {
Stephen Crane7bca1052021-10-25 17:52:51 -07001146 $( #[$attr:meta] )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001147 $enum:ident : [$backing:ty; $size:expr] {
Jooyung Han70d92812022-03-18 15:29:54 +09001148 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001149 }
1150 } => {
Stephen Crane7bca1052021-10-25 17:52:51 -07001151 $( #[$attr] )*
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001152 #[derive(Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001153 #[allow(missing_docs)]
Andrei Homescu00eca712020-09-09 18:57:40 -07001154 pub struct $enum(pub $backing);
1155 impl $enum {
Jooyung Han70d92812022-03-18 15:29:54 +09001156 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001157
1158 #[inline(always)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001159 #[allow(missing_docs)]
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001160 pub const fn enum_values() -> [Self; $size] {
1161 [$(Self::$name),*]
1162 }
Andrei Homescu00eca712020-09-09 18:57:40 -07001163 }
1164
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001165 impl std::fmt::Debug for $enum {
1166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1167 match self.0 {
1168 $($value => f.write_str(stringify!($name)),)*
1169 _ => f.write_fmt(format_args!("{}", self.0))
1170 }
1171 }
1172 }
1173
Stephen Cranef2735b42022-01-19 17:49:46 +00001174 impl $crate::binder_impl::Serialize for $enum {
1175 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001176 parcel.write(&self.0)
1177 }
1178 }
1179
Stephen Cranef2735b42022-01-19 17:49:46 +00001180 impl $crate::binder_impl::SerializeArray for $enum {
1181 fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001182 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
Stephen Cranef2735b42022-01-19 17:49:46 +00001183 <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel)
Andrei Homescu00eca712020-09-09 18:57:40 -07001184 }
1185 }
1186
Stephen Cranef2735b42022-01-19 17:49:46 +00001187 impl $crate::binder_impl::Deserialize for $enum {
Andrei Homescu2b802f72023-05-05 03:21:43 +00001188 type UninitType = Self;
1189 fn uninit() -> Self::UninitType { Self::UninitType::default() }
1190 fn from_init(value: Self) -> Self::UninitType { value }
1191
Stephen Cranef2735b42022-01-19 17:49:46 +00001192 fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001193 parcel.read().map(Self)
1194 }
1195 }
1196
Stephen Cranef2735b42022-01-19 17:49:46 +00001197 impl $crate::binder_impl::DeserializeArray for $enum {
1198 fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001199 let v: Option<Vec<$backing>> =
Stephen Cranef2735b42022-01-19 17:49:46 +00001200 <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?;
Andrei Homescu00eca712020-09-09 18:57:40 -07001201 Ok(v.map(|v| v.into_iter().map(Self).collect()))
1202 }
1203 }
1204 };
1205}