blob: 23026e593c9a01b93d1733ab2537b4e547c5f0ba [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.
210pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800211/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
212pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000213
214/// Internal interface of binder local or remote objects for making
215/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700216///
Andrew Walbran12400d82021-03-04 17:04:34 +0000217/// This trait corresponds to the parts of the interface of the C++ `IBinder`
218/// class which are internal implementation details.
219pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700220 /// Is this object still alive?
221 fn is_binder_alive(&self) -> bool;
222
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700223 /// Indicate that the service intends to receive caller security contexts.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800224 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700225 fn set_requesting_sid(&mut self, enable: bool);
226
Stephen Crane2a3c2502020-06-16 17:48:35 -0700227 /// Dump this object to the given file handle
228 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
229
230 /// Get a new interface that exposes additional extension functionality, if
231 /// available.
232 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
233
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000234 /// Create a Parcel that can be used with `submit_transact`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000235 fn prepare_transact(&self) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000236
Stephen Crane2a3c2502020-06-16 17:48:35 -0700237 /// Perform a generic operation with the object.
238 ///
Alice Ryhl8618c482021-11-09 15:35:35 +0000239 /// The provided [`Parcel`] must have been created by a call to
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000240 /// `prepare_transact` on the same binder.
241 ///
242 /// # Arguments
243 ///
244 /// * `code` - Transaction code for the operation.
Alice Ryhl8618c482021-11-09 15:35:35 +0000245 /// * `data` - [`Parcel`] with input data.
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000246 /// * `flags` - Transaction flags, e.g. marking the transaction as
247 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
248 fn submit_transact(
249 &self,
250 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000251 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000252 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000253 ) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000254
255 /// Perform a generic operation with the object. This is a convenience
256 /// method that internally calls `prepare_transact` followed by
257 /// `submit_transact.
258 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700259 /// # Arguments
260 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700261 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000262 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000263 /// * `input_callback` A callback for building the `Parcel`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000264 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
Stephen Crane2a3c2502020-06-16 17:48:35 -0700265 &self,
266 code: TransactionCode,
267 flags: TransactionFlags,
268 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000269 ) -> Result<Parcel> {
270 let mut parcel = self.prepare_transact()?;
Alice Ryhl8618c482021-11-09 15:35:35 +0000271 input_callback(parcel.borrowed())?;
272 self.submit_transact(code, parcel, flags)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000273 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000274}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700275
Andrew Walbran12400d82021-03-04 17:04:34 +0000276/// Interface of binder local or remote objects.
277///
278/// This trait corresponds to the parts of the interface of the C++ `IBinder`
279/// class which are public.
280pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700281 /// Register the recipient for a notification if this binder
282 /// goes away. If this binder object unexpectedly goes away
283 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000284 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700285 ///
286 /// You will only receive death notifications for remote binders,
287 /// as local binders by definition can't die without you dying as well.
288 /// Trying to use this function on a local binder will result in an
289 /// INVALID_OPERATION code being returned and nothing happening.
290 ///
Andrew Walbranfee58632023-06-22 17:36:48 +0000291 /// This link only holds a weak reference to its recipient. If the
292 /// `DeathRecipient` is dropped then it will be unlinked.
293 ///
294 /// Note that the notifications won't work if you don't first start at least
295 /// one Binder thread by calling
296 /// [`ProcessState::start_thread_pool`](crate::ProcessState::start_thread_pool)
297 /// or
298 /// [`ProcessState::join_thread_pool`](crate::ProcessState::join_thread_pool).
Stephen Crane2a3c2502020-06-16 17:48:35 -0700299 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
300
301 /// Remove a previously registered death notification.
302 /// The recipient will no longer be called if this object
303 /// dies.
304 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
Stephen Crane61366d42022-01-20 17:45:34 -0800305
306 /// Send a ping transaction to this object
307 fn ping_binder(&mut self) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700308}
309
310/// Opaque reference to the type of a Binder interface.
311///
312/// This object encapsulates the Binder interface descriptor string, along with
313/// the binder transaction callback, if the class describes a local service.
314///
315/// A Binder remotable object may only have a single interface class, and any
316/// given object can only be associated with one class. Two objects with
317/// different classes are incompatible, even if both classes have the same
318/// interface descriptor.
319#[derive(Copy, Clone, PartialEq, Eq)]
320pub struct InterfaceClass(*const sys::AIBinder_Class);
321
322impl InterfaceClass {
323 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
324 ///
325 /// Note: the returned pointer will not be constant. Calling this method
326 /// multiple times for the same type will result in distinct class
327 /// pointers. A static getter for this value is implemented in
Andrei Homescu3e9c13a2023-05-09 02:48:22 +0000328 /// [`crate::declare_binder_interface!`].
Stephen Crane2a3c2502020-06-16 17:48:35 -0700329 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
330 let descriptor = CString::new(I::get_descriptor()).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100331 // Safety: `AIBinder_Class_define` expects a valid C string, and three
332 // valid callback functions, all non-null pointers. The C string is
333 // copied and need not be valid for longer than the call, so we can drop
334 // it after the call. We can safely assign null to the onDump and
335 // handleShellCommand callbacks as long as the class pointer was
336 // non-null. Rust None for a Option<fn> is guaranteed to be a NULL
337 // pointer. Rust retains ownership of the pointer after it is defined.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700338 let ptr = unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700339 let class = sys::AIBinder_Class_define(
340 descriptor.as_ptr(),
341 Some(I::on_create),
342 Some(I::on_destroy),
343 Some(I::on_transact),
344 );
345 if class.is_null() {
346 panic!("Expected non-null class pointer from AIBinder_Class_define!");
347 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700348 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700349 sys::AIBinder_Class_setHandleShellCommand(class, None);
350 class
351 };
352 InterfaceClass(ptr)
353 }
354
355 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
356 /// pointer.
357 ///
358 /// # Safety
359 ///
360 /// This function is safe iff `ptr` is a valid, non-null pointer to an
361 /// `AIBinder_Class`.
362 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
363 InterfaceClass(ptr)
364 }
Stephen Crane669deb62020-09-10 17:31:39 -0700365
366 /// Get the interface descriptor string of this class.
367 pub fn get_descriptor(&self) -> String {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100368 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor is
369 // always a two-byte null terminated sequence of u16s. Thus, we can
370 // continue reading from the pointer until we hit a null value, and this
371 // pointer can be a valid slice if the slice length is <= the number of
372 // u16 elements before the null terminator.
Stephen Crane669deb62020-09-10 17:31:39 -0700373 unsafe {
Stephen Crane669deb62020-09-10 17:31:39 -0700374 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000375 CStr::from_ptr(raw_descriptor)
376 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700377 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
378 .into()
379 }
380 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700381}
382
383impl From<InterfaceClass> for *const sys::AIBinder_Class {
384 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
385 class.0
386 }
387}
388
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800389/// Strong reference to a binder object
390pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
391
392impl<I: FromIBinder + ?Sized> Strong<I> {
393 /// Create a new strong reference to the provided binder object
394 pub fn new(binder: Box<I>) -> Self {
395 Self(binder)
396 }
397
398 /// Construct a new weak reference to this binder
399 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
400 Weak::new(this)
401 }
Alice Ryhlc1736842021-11-23 12:38:51 +0000402
403 /// Convert this synchronous binder handle into an asynchronous one.
404 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
405 where
406 I: ToAsyncInterface<P>,
407 {
408 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder
409 // object is also valid for the target type.
410 FromIBinder::try_from(self.0.as_binder()).unwrap()
411 }
412
413 /// Convert this asynchronous binder handle into a synchronous one.
414 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
415 where
416 I: ToSyncInterface,
417 {
418 // By implementing the ToSyncInterface trait, it is guaranteed that the binder
419 // object is also valid for the target type.
420 FromIBinder::try_from(self.0.as_binder()).unwrap()
421 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800422}
423
424impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
425 fn clone(&self) -> Self {
426 // Since we hold a strong reference, we should always be able to create
427 // a new strong reference to the same interface type, so try_from()
428 // should never fail here.
429 FromIBinder::try_from(self.0.as_binder()).unwrap()
430 }
431}
432
433impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
434 fn borrow(&self) -> &I {
435 &self.0
436 }
437}
438
439impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
440 fn as_ref(&self) -> &I {
441 &self.0
442 }
443}
444
445impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
446 type Target = I;
447
448 fn deref(&self) -> &Self::Target {
449 &self.0
450 }
451}
452
453impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
454 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
455 fmt::Debug::fmt(&**self, f)
456 }
457}
458
459impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
460 fn cmp(&self, other: &Self) -> Ordering {
461 self.0.as_binder().cmp(&other.0.as_binder())
462 }
463}
464
465impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
466 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Charisee Chiwad1b27c2023-10-12 16:02:39 -0700467 Some(self.cmp(other))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800468 }
469}
470
471impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
472 fn eq(&self, other: &Self) -> bool {
473 self.0.as_binder().eq(&other.0.as_binder())
474 }
475}
476
477impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
478
479/// Weak reference to a binder object
480#[derive(Debug)]
481pub struct Weak<I: FromIBinder + ?Sized> {
482 weak_binder: WpIBinder,
483 interface_type: PhantomData<I>,
484}
485
486impl<I: FromIBinder + ?Sized> Weak<I> {
487 /// Construct a new weak reference from a strong reference
488 fn new(binder: &Strong<I>) -> Self {
489 let weak_binder = binder.as_binder().downgrade();
Matthew Maurere268a9f2022-07-26 09:31:30 -0700490 Weak { weak_binder, interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800491 }
492
493 /// Upgrade this weak reference to a strong reference if the binder object
494 /// is still alive
495 pub fn upgrade(&self) -> Result<Strong<I>> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700496 self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from)
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800497 }
498}
499
500impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
501 fn clone(&self) -> Self {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700502 Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800503 }
504}
505
506impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
507 fn cmp(&self, other: &Self) -> Ordering {
508 self.weak_binder.cmp(&other.weak_binder)
509 }
510}
511
512impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
513 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Charisee Chiwad1b27c2023-10-12 16:02:39 -0700514 Some(self.cmp(other))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800515 }
516}
517
518impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
519 fn eq(&self, other: &Self) -> bool {
520 self.weak_binder == other.weak_binder
521 }
522}
523
524impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
525
Stephen Crane2a3c2502020-06-16 17:48:35 -0700526/// Create a function implementing a static getter for an interface class.
527///
528/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
529/// [`Interface`]) must have global, static class that uniquely identifies
530/// it. This macro implements an [`InterfaceClass`] getter to simplify these
531/// implementations.
532///
533/// The type of a structure that implements [`InterfaceClassMethods`] must be
534/// passed to this macro. For local services, this should be `Binder<Self>`
535/// since [`Binder`] implements [`InterfaceClassMethods`].
536///
537/// # Examples
538///
539/// When implementing a local [`Remotable`] service `ExampleService`, the
540/// `get_class` method is required in the [`Remotable`] impl block. This macro
541/// should be used as follows to implement this functionality:
542///
543/// ```rust
544/// impl Remotable for ExampleService {
545/// fn get_descriptor() -> &'static str {
546/// "android.os.IExampleInterface"
547/// }
548///
549/// fn on_transact(
550/// &self,
551/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000552/// data: &BorrowedParcel,
553/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700554/// ) -> Result<()> {
555/// // ...
556/// }
557///
558/// binder_fn_get_class!(Binder<Self>);
559/// }
560/// ```
561macro_rules! binder_fn_get_class {
562 ($class:ty) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000563 binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700564 };
565
566 ($constructor:expr) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000567 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700568 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000569 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700570
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100571 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
572 // variable, and therefore is thread-safe, as it can only occur
573 // once.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700574 CLASS_INIT.call_once(|| unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700575 CLASS = Some($constructor);
576 });
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100577 // Safety: The `CLASS` variable can only be mutated once, above, and
578 // is subsequently safe to read from any thread.
579 unsafe { CLASS.unwrap() }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700580 }
581 };
582}
583
584pub trait InterfaceClassMethods {
585 /// Get the interface descriptor string for this object type.
586 fn get_descriptor() -> &'static str
587 where
588 Self: Sized;
589
590 /// Called during construction of a new `AIBinder` object of this interface
591 /// class.
592 ///
593 /// The opaque pointer parameter will be the parameter provided to
594 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
595 /// `AIBinder` object.
596 ///
597 /// # Safety
598 ///
599 /// Callback called from C++. The parameter argument provided to
600 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
601 /// will take ownership of the returned pointer, which it will free via
602 /// `on_destroy`.
603 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
604
605 /// Called when a transaction needs to be processed by the local service
606 /// implementation.
607 ///
608 /// # Safety
609 ///
610 /// Callback called from C++. The `binder` parameter must be a valid pointer
611 /// to a binder object of this class with userdata initialized via this
612 /// class's `on_create`. The parcel parameters must be valid pointers to
613 /// parcel objects.
614 unsafe extern "C" fn on_transact(
615 binder: *mut sys::AIBinder,
616 code: u32,
617 data: *const sys::AParcel,
618 reply: *mut sys::AParcel,
619 ) -> status_t;
620
621 /// Called whenever an `AIBinder` object is no longer referenced and needs
622 /// to be destroyed.
623 ///
624 /// # Safety
625 ///
626 /// Callback called from C++. The opaque pointer parameter must be the value
627 /// returned by `on_create` for this class. This function takes ownership of
628 /// the provided pointer and destroys it.
629 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700630
631 /// Called to handle the `dump` transaction.
632 ///
633 /// # Safety
634 ///
635 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
636 /// contains a `T` pointer in its user data. fd should be a non-owned file
637 /// descriptor, and args must be an array of null-terminated string
638 /// poiinters with length num_args.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700639 unsafe extern "C" fn on_dump(
640 binder: *mut sys::AIBinder,
641 fd: i32,
642 args: *mut *const c_char,
643 num_args: u32,
644 ) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700645}
646
647/// Interface for transforming a generic SpIBinder into a specific remote
648/// interface trait.
649///
650/// # Example
651///
652/// For Binder interface `IFoo`, the following implementation should be made:
653/// ```no_run
654/// # use binder::{FromIBinder, SpIBinder, Result};
655/// # trait IFoo {}
656/// impl FromIBinder for dyn IFoo {
657/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
658/// // ...
659/// # Err(binder::StatusCode::OK)
660/// }
661/// }
662/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800663pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700664 /// Try to interpret a generic Binder object as this interface.
665 ///
666 /// Returns a trait object for the `Self` interface if this object
667 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800668 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700669}
670
671/// Trait for transparent Rust wrappers around android C++ native types.
672///
673/// The pointer return by this trait's methods should be immediately passed to
674/// C++ and not stored by Rust. The pointer is valid only as long as the
675/// underlying C++ object is alive, so users must be careful to take this into
676/// account, as Rust cannot enforce this.
677///
678/// # Safety
679///
680/// For this trait to be a correct implementation, `T` must be a valid android
681/// C++ type. Since we cannot constrain this via the type system, this trait is
682/// marked as unsafe.
683pub unsafe trait AsNative<T> {
684 /// Return a pointer to the native version of `self`
685 fn as_native(&self) -> *const T;
686
687 /// Return a mutable pointer to the native version of `self`
688 fn as_native_mut(&mut self) -> *mut T;
689}
690
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100691// Safety: If V is a valid Android C++ type then we can either use that or a
692// null pointer.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700693unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
694 fn as_native(&self) -> *const T {
695 self.as_ref().map_or(ptr::null(), |v| v.as_native())
696 }
697
698 fn as_native_mut(&mut self) -> *mut T {
699 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
700 }
701}
702
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000703/// The features to enable when creating a native Binder.
704///
705/// This should always be initialised with a default value, e.g.:
706/// ```
707/// # use binder::BinderFeatures;
708/// BinderFeatures {
709/// set_requesting_sid: true,
710/// ..BinderFeatures::default(),
711/// }
712/// ```
713#[derive(Clone, Debug, Default, Eq, PartialEq)]
714pub struct BinderFeatures {
715 /// Indicates that the service intends to receive caller security contexts. This must be true
716 /// for `ThreadState::with_calling_sid` to work.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800717 #[cfg(not(android_vndk))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000718 pub set_requesting_sid: bool,
719 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
720 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
721 // expressions entirely.
722 #[doc(hidden)]
723 pub _non_exhaustive: (),
724}
725
Stephen Crane2a3c2502020-06-16 17:48:35 -0700726/// Declare typed interfaces for a binder object.
727///
728/// Given an interface trait and descriptor string, create a native and remote
729/// proxy wrapper for this interface. The native service object (`$native`)
730/// implements `Remotable` and will dispatch to the function `$on_transact` to
731/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
732/// objects for this interface and can optionally contain additional fields.
733///
734/// Assuming the interface trait is `Interface`, `$on_transact` function must
735/// have the following type:
736///
737/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000738/// # use binder::{Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700739/// # trait Placeholder {
740/// fn on_transact(
741/// service: &dyn Interface,
742/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000743/// data: &BorrowedParcel,
744/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700745/// ) -> binder::Result<()>;
746/// # }
747/// ```
748///
749/// # Examples
750///
751/// The following example declares the local service type `BnServiceManager` and
752/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
753/// proxy respectively) for the `IServiceManager` Binder interface. The
754/// interfaces will be identified by the descriptor string
755/// "android.os.IServiceManager". The local service will dispatch transactions
756/// using the provided function, `on_transact`.
757///
758/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000759/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700760///
761/// pub trait IServiceManager: Interface {
762/// // remote methods...
763/// }
764///
765/// declare_binder_interface! {
766/// IServiceManager["android.os.IServiceManager"] {
767/// native: BnServiceManager(on_transact),
768/// proxy: BpServiceManager,
769/// }
770/// }
771///
772/// fn on_transact(
773/// service: &dyn IServiceManager,
774/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000775/// data: &BorrowedParcel,
776/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700777/// ) -> binder::Result<()> {
778/// // ...
779/// Ok(())
780/// }
781///
782/// impl IServiceManager for BpServiceManager {
783/// // parceling/unparceling code for the IServiceManager emitted here
784/// }
785///
786/// impl IServiceManager for Binder<BnServiceManager> {
787/// // Forward calls to local implementation
788/// }
789/// ```
790#[macro_export]
791macro_rules! declare_binder_interface {
792 {
793 $interface:path[$descriptor:expr] {
794 native: $native:ident($on_transact:path),
795 proxy: $proxy:ident,
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000796 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700797 }
798 } => {
799 $crate::declare_binder_interface! {
800 $interface[$descriptor] {
801 native: $native($on_transact),
802 proxy: $proxy {},
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000803 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000804 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800805 }
806 }
807 };
808
809 {
810 $interface:path[$descriptor:expr] {
811 native: $native:ident($on_transact:path),
812 proxy: $proxy:ident,
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000813 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800814 stability: $stability:expr,
815 }
816 } => {
817 $crate::declare_binder_interface! {
818 $interface[$descriptor] {
819 native: $native($on_transact),
820 proxy: $proxy {},
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000821 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800822 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700823 }
824 }
825 };
826
827 {
828 $interface:path[$descriptor:expr] {
829 native: $native:ident($on_transact:path),
830 proxy: $proxy:ident {
831 $($fname:ident: $fty:ty = $finit:expr),*
832 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000833 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700834 }
835 } => {
836 $crate::declare_binder_interface! {
837 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800838 native: $native($on_transact),
839 proxy: $proxy {
840 $($fname: $fty = $finit),*
841 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000842 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000843 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800844 }
845 }
846 };
847
848 {
849 $interface:path[$descriptor:expr] {
850 native: $native:ident($on_transact:path),
851 proxy: $proxy:ident {
852 $($fname:ident: $fty:ty = $finit:expr),*
853 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000854 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800855 stability: $stability:expr,
856 }
857 } => {
858 $crate::declare_binder_interface! {
859 $interface[$descriptor] {
Stephen Cranef2735b42022-01-19 17:49:46 +0000860 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700861 native: $native($on_transact),
Stephen Cranef2735b42022-01-19 17:49:46 +0000862 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700863 proxy: $proxy {
864 $($fname: $fty = $finit),*
865 },
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000866 $(async: $async_interface $(($try_into_local_async))?,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800867 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700868 }
869 }
870 };
871
872 {
873 $interface:path[$descriptor:expr] {
874 @doc[$native_doc:expr]
875 native: $native:ident($on_transact:path),
876
877 @doc[$proxy_doc:expr]
878 proxy: $proxy:ident {
879 $($fname:ident: $fty:ty = $finit:expr),*
880 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800881
Alice Ryhl0ae829e2024-05-21 14:21:22 +0000882 $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000883
Stephen Craneff7f03a2021-02-25 16:04:22 -0800884 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700885 }
886 } => {
887 #[doc = $proxy_doc]
888 pub struct $proxy {
889 binder: $crate::SpIBinder,
890 $($fname: $fty,)*
891 }
892
893 impl $crate::Interface for $proxy {
894 fn as_binder(&self) -> $crate::SpIBinder {
895 self.binder.clone()
896 }
897 }
898
Stephen Cranef2735b42022-01-19 17:49:46 +0000899 impl $crate::binder_impl::Proxy for $proxy
Stephen Crane2a3c2502020-06-16 17:48:35 -0700900 where
901 $proxy: $interface,
902 {
903 fn get_descriptor() -> &'static str {
904 $descriptor
905 }
906
Stephen Cranef2735b42022-01-19 17:49:46 +0000907 fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> {
Stephen Crane669deb62020-09-10 17:31:39 -0700908 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700909 }
910 }
911
912 #[doc = $native_doc]
913 #[repr(transparent)]
914 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
915
916 impl $native {
917 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000918 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 +0000919 let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability);
Janis Danisevskis1323d512021-11-09 07:48:08 -0800920 #[cfg(not(android_vndk))]
Stephen Cranef2735b42022-01-19 17:49:46 +0000921 $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800922 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700923 }
Orlando Arbildod0880e82023-10-09 17:36:17 +0000924
925 /// Tries to downcast the interface to another type.
926 /// When receiving this object from a binder call, make sure that the object received is
927 /// a binder native object and that is of the right type for the Downcast:
928 ///
929 /// let binder = received_object.as_binder();
930 /// if !binder.is_remote() {
931 /// let binder_native: Binder<BnFoo> = binder.try_into()?;
932 /// let original_object = binder_native.downcast_binder::<MyFoo>();
933 /// // Check that returned type is not None before using it
934 /// }
935 ///
936 /// Handle the error cases instead of just calling `unwrap` or `expect` to prevent a
937 /// malicious caller to mount a Denial of Service attack.
938 pub fn downcast_binder<T: $interface>(&self) -> Option<&T> {
939 self.0.as_any().downcast_ref::<T>()
940 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700941 }
942
Stephen Cranef2735b42022-01-19 17:49:46 +0000943 impl $crate::binder_impl::Remotable for $native {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700944 fn get_descriptor() -> &'static str {
945 $descriptor
946 }
947
Stephen Cranef2735b42022-01-19 17:49:46 +0000948 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 -0700949 match $on_transact(&*self.0, code, data, reply) {
950 // The C++ backend converts UNEXPECTED_NULL into an exception
951 Err($crate::StatusCode::UNEXPECTED_NULL) => {
952 let status = $crate::Status::new_exception(
953 $crate::ExceptionCode::NULL_POINTER,
954 None,
955 );
956 reply.write(&status)
957 },
958 result => result
959 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700960 }
961
Andrei Homescud23c0492023-11-09 01:51:59 +0000962 fn on_dump(&self, writer: &mut dyn std::io::Write, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> {
963 self.0.dump(writer, args)
Stephen Crane2a3297f2021-06-11 16:48:10 -0700964 }
965
Stephen Cranef2735b42022-01-19 17:49:46 +0000966 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700967 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000968 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700969
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100970 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
971 // variable, and therefore is thread-safe, as it can only occur
972 // once.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700973 CLASS_INIT.call_once(|| unsafe {
Stephen Cranef2735b42022-01-19 17:49:46 +0000974 CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700975 });
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100976 // Safety: The `CLASS` variable can only be mutated once, above,
977 // and is subsequently safe to read from any thread.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700978 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700979 CLASS.unwrap()
980 }
981 }
982 }
983
984 impl $crate::FromIBinder for dyn $interface {
Stephen Cranef2735b42022-01-19 17:49:46 +0000985 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> {
986 use $crate::binder_impl::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700987
988 let existing_class = ibinder.get_class();
989 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +0000990 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
991 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Stephen Crane669deb62020-09-10 17:31:39 -0700992 {
993 // The binder object's descriptor string matches what we
994 // expect. We still need to treat this local or already
995 // associated object as remote, because we can't cast it
996 // into a Rust service object without a matching class
997 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +0000998 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700999 }
Stephen Crane2a3c2502020-06-16 17:48:35 -07001000 }
1001
Stephen Cranef2735b42022-01-19 17:49:46 +00001002 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
1003 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Stephen Crane669deb62020-09-10 17:31:39 -07001004 std::convert::TryFrom::try_from(ibinder.clone());
1005 if let Ok(service) = service {
1006 // We were able to associate with our expected class and
1007 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001008 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -07001009 } else {
1010 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +00001011 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -07001012 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +00001013 }
Stephen Crane669deb62020-09-10 17:31:39 -07001014
1015 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -07001016 }
1017 }
1018
Stephen Cranef2735b42022-01-19 17:49:46 +00001019 impl $crate::binder_impl::Serialize for dyn $interface + '_
Stephen Crane2a3c2502020-06-16 17:48:35 -07001020 where
Stephen Craned58bce02020-07-07 12:26:02 -07001021 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -07001022 {
Stephen Cranef2735b42022-01-19 17:49:46 +00001023 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -07001024 let binder = $crate::Interface::as_binder(self);
1025 parcel.write(&binder)
1026 }
1027 }
1028
Stephen Cranef2735b42022-01-19 17:49:46 +00001029 impl $crate::binder_impl::SerializeOption for dyn $interface + '_ {
1030 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -07001031 parcel.write(&this.map($crate::Interface::as_binder))
1032 }
1033 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -07001034
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001035 impl std::fmt::Debug for dyn $interface + '_ {
Andrei Homescu2e3c1472020-08-11 16:35:40 -07001036 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1037 f.pad(stringify!($interface))
1038 }
1039 }
Andrei Homescu64ebd132020-08-07 22:12:48 -07001040
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001041 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -07001042 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001043 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -07001044 fn to_owned(&self) -> Self::Owned {
1045 self.as_binder().into_interface()
1046 .expect(concat!("Error cloning interface ", stringify!($interface)))
1047 }
1048 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001049
1050 $(
1051 // Async interface trait implementations.
Orlando Arbildod0880e82023-10-09 17:36:17 +00001052 impl<P: $crate::BinderAsyncPool + 'static> $crate::FromIBinder for dyn $async_interface<P> {
Stephen Cranef2735b42022-01-19 17:49:46 +00001053 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
1054 use $crate::binder_impl::AssociateClass;
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001055
1056 let existing_class = ibinder.get_class();
1057 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +00001058 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
1059 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001060 {
1061 // The binder object's descriptor string matches what we
1062 // expect. We still need to treat this local or already
1063 // associated object as remote, because we can't cast it
1064 // into a Rust service object without a matching class
1065 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +00001066 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001067 }
1068 }
1069
Stephen Cranef2735b42022-01-19 17:49:46 +00001070 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
Alice Ryhl0ae829e2024-05-21 14:21:22 +00001071 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
1072 std::convert::TryFrom::try_from(ibinder.clone());
1073 $(
1074 // This part is only generated if the user of the macro specifies that the
1075 // trait has an `try_into_local_async` implementation.
1076 if let Ok(service) = service {
1077 if let Some(async_service) = $native::$try_into_local_async(service) {
1078 // We were able to associate with our expected class,
1079 // the service is local, and the local service is async.
1080 return Ok(async_service);
1081 }
1082 // The service is local but not async. Fall back to treating it as a
1083 // remote service. This means that calls to this local service have an
1084 // extra performance cost due to serialization, but async handle to
1085 // non-async server is considered a rare case, so this is okay.
1086 }
1087 )?
1088 // Treat service as remote.
Alice Ryhleed9ac12023-07-25 13:45:47 +00001089 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001090 }
1091
1092 Err($crate::StatusCode::BAD_TYPE.into())
1093 }
1094 }
1095
Orlando Arbildod0880e82023-10-09 17:36:17 +00001096 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
Stephen Cranef2735b42022-01-19 17:49:46 +00001097 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001098 let binder = $crate::Interface::as_binder(self);
1099 parcel.write(&binder)
1100 }
1101 }
1102
Orlando Arbildod0880e82023-10-09 17:36:17 +00001103 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
Stephen Cranef2735b42022-01-19 17:49:46 +00001104 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001105 parcel.write(&this.map($crate::Interface::as_binder))
1106 }
1107 }
1108
Orlando Arbildod0880e82023-10-09 17:36:17 +00001109 impl<P: $crate::BinderAsyncPool + 'static> std::fmt::Debug for dyn $async_interface<P> + '_ {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1111 f.pad(stringify!($async_interface))
1112 }
1113 }
1114
1115 /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
Orlando Arbildod0880e82023-10-09 17:36:17 +00001116 impl<P: $crate::BinderAsyncPool + 'static> std::borrow::ToOwned for dyn $async_interface<P> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001117 type Owned = $crate::Strong<dyn $async_interface<P>>;
1118 fn to_owned(&self) -> Self::Owned {
1119 self.as_binder().into_interface()
1120 .expect(concat!("Error cloning interface ", stringify!($async_interface)))
1121 }
1122 }
Alice Ryhlc1736842021-11-23 12:38:51 +00001123
Orlando Arbildod0880e82023-10-09 17:36:17 +00001124 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
Alice Ryhlc1736842021-11-23 12:38:51 +00001125 type Target = dyn $async_interface<P>;
1126 }
1127
Orlando Arbildod0880e82023-10-09 17:36:17 +00001128 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
Alice Ryhlc1736842021-11-23 12:38:51 +00001129 type Target = dyn $interface;
1130 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001131 )?
Stephen Crane2a3c2502020-06-16 17:48:35 -07001132 };
1133}
Andrei Homescu00eca712020-09-09 18:57:40 -07001134
1135/// Declare an AIDL enumeration.
1136///
1137/// This is mainly used internally by the AIDL compiler.
1138#[macro_export]
1139macro_rules! declare_binder_enum {
1140 {
Stephen Crane7bca1052021-10-25 17:52:51 -07001141 $( #[$attr:meta] )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001142 $enum:ident : [$backing:ty; $size:expr] {
Jooyung Han70d92812022-03-18 15:29:54 +09001143 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001144 }
1145 } => {
Stephen Crane7bca1052021-10-25 17:52:51 -07001146 $( #[$attr] )*
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001147 #[derive(Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001148 #[allow(missing_docs)]
Andrei Homescu00eca712020-09-09 18:57:40 -07001149 pub struct $enum(pub $backing);
1150 impl $enum {
Jooyung Han70d92812022-03-18 15:29:54 +09001151 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001152
1153 #[inline(always)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001154 #[allow(missing_docs)]
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001155 pub const fn enum_values() -> [Self; $size] {
1156 [$(Self::$name),*]
1157 }
Andrei Homescu00eca712020-09-09 18:57:40 -07001158 }
1159
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001160 impl std::fmt::Debug for $enum {
1161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1162 match self.0 {
1163 $($value => f.write_str(stringify!($name)),)*
1164 _ => f.write_fmt(format_args!("{}", self.0))
1165 }
1166 }
1167 }
1168
Stephen Cranef2735b42022-01-19 17:49:46 +00001169 impl $crate::binder_impl::Serialize for $enum {
1170 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001171 parcel.write(&self.0)
1172 }
1173 }
1174
Stephen Cranef2735b42022-01-19 17:49:46 +00001175 impl $crate::binder_impl::SerializeArray for $enum {
1176 fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001177 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
Stephen Cranef2735b42022-01-19 17:49:46 +00001178 <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel)
Andrei Homescu00eca712020-09-09 18:57:40 -07001179 }
1180 }
1181
Stephen Cranef2735b42022-01-19 17:49:46 +00001182 impl $crate::binder_impl::Deserialize for $enum {
Andrei Homescu2b802f72023-05-05 03:21:43 +00001183 type UninitType = Self;
1184 fn uninit() -> Self::UninitType { Self::UninitType::default() }
1185 fn from_init(value: Self) -> Self::UninitType { value }
1186
Stephen Cranef2735b42022-01-19 17:49:46 +00001187 fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001188 parcel.read().map(Self)
1189 }
1190 }
1191
Stephen Cranef2735b42022-01-19 17:49:46 +00001192 impl $crate::binder_impl::DeserializeArray for $enum {
1193 fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001194 let v: Option<Vec<$backing>> =
Stephen Cranef2735b42022-01-19 17:49:46 +00001195 <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?;
Andrei Homescu00eca712020-09-09 18:57:40 -07001196 Ok(v.map(|v| v.into_iter().map(Self).collect()))
1197 }
1198 }
1199 };
1200}