blob: 78f8877c1d087ce6f3a371c0f8ffec3c4c96a194 [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;
Stephen Crane2a3297f2021-06-11 16:48:10 -070030use std::fs::File;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080031use std::marker::PhantomData;
32use std::ops::Deref;
Stephen Crane669deb62020-09-10 17:31:39 -070033use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070034use std::os::unix::io::AsRawFd;
35use 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.
65 fn dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
66 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
Stephen Crane2a3c2502020-06-16 17:48:35 -0700139/// A local service that can be remotable via Binder.
140///
141/// An object that implement this interface made be made into a Binder service
142/// via `Binder::new(object)`.
143///
144/// This is a low-level interface that should normally be automatically
Andrei Homescu3e9c13a2023-05-09 02:48:22 +0000145/// generated from AIDL via the [`crate::declare_binder_interface!`] macro.
146/// When using the AIDL backend, users need only implement the high-level AIDL-defined
Stephen Crane2a3c2502020-06-16 17:48:35 -0700147/// interface. The AIDL compiler then generates a container struct that wraps
148/// the user-defined service and implements `Remotable`.
Orlando Arbildod0880e82023-10-09 17:36:17 +0000149pub trait Remotable: Send + Sync + 'static {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700150 /// The Binder interface descriptor string.
151 ///
152 /// This string is a unique identifier for a Binder interface, and should be
153 /// the same between all implementations of that interface.
154 fn get_descriptor() -> &'static str;
155
156 /// Handle and reply to a request to invoke a transaction on this object.
157 ///
158 /// `reply` may be [`None`] if the sender does not expect a reply.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700159 fn on_transact(
160 &self,
161 code: TransactionCode,
162 data: &BorrowedParcel<'_>,
163 reply: &mut BorrowedParcel<'_>,
164 ) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700165
Stephen Crane2a3297f2021-06-11 16:48:10 -0700166 /// Handle a request to invoke the dump transaction on this
167 /// object.
168 fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>;
169
Stephen Crane2a3c2502020-06-16 17:48:35 -0700170 /// Retrieve the class of this remote object.
171 ///
172 /// This method should always return the same InterfaceClass for the same
173 /// type.
174 fn get_class() -> InterfaceClass;
175}
176
Andrew Walbran12400d82021-03-04 17:04:34 +0000177/// First transaction code available for user commands (inclusive)
178pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
179/// Last transaction code available for user commands (inclusive)
180pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
181
182/// Corresponds to TF_ONE_WAY -- an asynchronous call.
183pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
184/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
185pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800186/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
187pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000188
189/// Internal interface of binder local or remote objects for making
190/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700191///
Andrew Walbran12400d82021-03-04 17:04:34 +0000192/// This trait corresponds to the parts of the interface of the C++ `IBinder`
193/// class which are internal implementation details.
194pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700195 /// Is this object still alive?
196 fn is_binder_alive(&self) -> bool;
197
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700198 /// Indicate that the service intends to receive caller security contexts.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800199 #[cfg(not(android_vndk))]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700200 fn set_requesting_sid(&mut self, enable: bool);
201
Stephen Crane2a3c2502020-06-16 17:48:35 -0700202 /// Dump this object to the given file handle
203 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
204
205 /// Get a new interface that exposes additional extension functionality, if
206 /// available.
207 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
208
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000209 /// Create a Parcel that can be used with `submit_transact`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000210 fn prepare_transact(&self) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000211
Stephen Crane2a3c2502020-06-16 17:48:35 -0700212 /// Perform a generic operation with the object.
213 ///
Alice Ryhl8618c482021-11-09 15:35:35 +0000214 /// The provided [`Parcel`] must have been created by a call to
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000215 /// `prepare_transact` on the same binder.
216 ///
217 /// # Arguments
218 ///
219 /// * `code` - Transaction code for the operation.
Alice Ryhl8618c482021-11-09 15:35:35 +0000220 /// * `data` - [`Parcel`] with input data.
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000221 /// * `flags` - Transaction flags, e.g. marking the transaction as
222 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
223 fn submit_transact(
224 &self,
225 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000226 data: Parcel,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000227 flags: TransactionFlags,
Alice Ryhl8618c482021-11-09 15:35:35 +0000228 ) -> Result<Parcel>;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000229
230 /// Perform a generic operation with the object. This is a convenience
231 /// method that internally calls `prepare_transact` followed by
232 /// `submit_transact.
233 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700234 /// # Arguments
235 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700236 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000237 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000238 /// * `input_callback` A callback for building the `Parcel`.
Alice Ryhl8618c482021-11-09 15:35:35 +0000239 fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
Stephen Crane2a3c2502020-06-16 17:48:35 -0700240 &self,
241 code: TransactionCode,
242 flags: TransactionFlags,
243 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000244 ) -> Result<Parcel> {
245 let mut parcel = self.prepare_transact()?;
Alice Ryhl8618c482021-11-09 15:35:35 +0000246 input_callback(parcel.borrowed())?;
247 self.submit_transact(code, parcel, flags)
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000248 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000249}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700250
Andrew Walbran12400d82021-03-04 17:04:34 +0000251/// Interface of binder local or remote objects.
252///
253/// This trait corresponds to the parts of the interface of the C++ `IBinder`
254/// class which are public.
255pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700256 /// Register the recipient for a notification if this binder
257 /// goes away. If this binder object unexpectedly goes away
258 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000259 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700260 ///
261 /// You will only receive death notifications for remote binders,
262 /// as local binders by definition can't die without you dying as well.
263 /// Trying to use this function on a local binder will result in an
264 /// INVALID_OPERATION code being returned and nothing happening.
265 ///
Andrew Walbranfee58632023-06-22 17:36:48 +0000266 /// This link only holds a weak reference to its recipient. If the
267 /// `DeathRecipient` is dropped then it will be unlinked.
268 ///
269 /// Note that the notifications won't work if you don't first start at least
270 /// one Binder thread by calling
271 /// [`ProcessState::start_thread_pool`](crate::ProcessState::start_thread_pool)
272 /// or
273 /// [`ProcessState::join_thread_pool`](crate::ProcessState::join_thread_pool).
Stephen Crane2a3c2502020-06-16 17:48:35 -0700274 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
275
276 /// Remove a previously registered death notification.
277 /// The recipient will no longer be called if this object
278 /// dies.
279 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
Stephen Crane61366d42022-01-20 17:45:34 -0800280
281 /// Send a ping transaction to this object
282 fn ping_binder(&mut self) -> Result<()>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700283}
284
285/// Opaque reference to the type of a Binder interface.
286///
287/// This object encapsulates the Binder interface descriptor string, along with
288/// the binder transaction callback, if the class describes a local service.
289///
290/// A Binder remotable object may only have a single interface class, and any
291/// given object can only be associated with one class. Two objects with
292/// different classes are incompatible, even if both classes have the same
293/// interface descriptor.
294#[derive(Copy, Clone, PartialEq, Eq)]
295pub struct InterfaceClass(*const sys::AIBinder_Class);
296
297impl InterfaceClass {
298 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
299 ///
300 /// Note: the returned pointer will not be constant. Calling this method
301 /// multiple times for the same type will result in distinct class
302 /// pointers. A static getter for this value is implemented in
Andrei Homescu3e9c13a2023-05-09 02:48:22 +0000303 /// [`crate::declare_binder_interface!`].
Stephen Crane2a3c2502020-06-16 17:48:35 -0700304 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
305 let descriptor = CString::new(I::get_descriptor()).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100306 // Safety: `AIBinder_Class_define` expects a valid C string, and three
307 // valid callback functions, all non-null pointers. The C string is
308 // copied and need not be valid for longer than the call, so we can drop
309 // it after the call. We can safely assign null to the onDump and
310 // handleShellCommand callbacks as long as the class pointer was
311 // non-null. Rust None for a Option<fn> is guaranteed to be a NULL
312 // pointer. Rust retains ownership of the pointer after it is defined.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700313 let ptr = unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700314 let class = sys::AIBinder_Class_define(
315 descriptor.as_ptr(),
316 Some(I::on_create),
317 Some(I::on_destroy),
318 Some(I::on_transact),
319 );
320 if class.is_null() {
321 panic!("Expected non-null class pointer from AIBinder_Class_define!");
322 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700323 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700324 sys::AIBinder_Class_setHandleShellCommand(class, None);
325 class
326 };
327 InterfaceClass(ptr)
328 }
329
330 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
331 /// pointer.
332 ///
333 /// # Safety
334 ///
335 /// This function is safe iff `ptr` is a valid, non-null pointer to an
336 /// `AIBinder_Class`.
337 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
338 InterfaceClass(ptr)
339 }
Stephen Crane669deb62020-09-10 17:31:39 -0700340
341 /// Get the interface descriptor string of this class.
342 pub fn get_descriptor(&self) -> String {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100343 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor is
344 // always a two-byte null terminated sequence of u16s. Thus, we can
345 // continue reading from the pointer until we hit a null value, and this
346 // pointer can be a valid slice if the slice length is <= the number of
347 // u16 elements before the null terminator.
Stephen Crane669deb62020-09-10 17:31:39 -0700348 unsafe {
Stephen Crane669deb62020-09-10 17:31:39 -0700349 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000350 CStr::from_ptr(raw_descriptor)
351 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700352 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
353 .into()
354 }
355 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700356}
357
358impl From<InterfaceClass> for *const sys::AIBinder_Class {
359 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
360 class.0
361 }
362}
363
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800364/// Strong reference to a binder object
365pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
366
367impl<I: FromIBinder + ?Sized> Strong<I> {
368 /// Create a new strong reference to the provided binder object
369 pub fn new(binder: Box<I>) -> Self {
370 Self(binder)
371 }
372
373 /// Construct a new weak reference to this binder
374 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
375 Weak::new(this)
376 }
Alice Ryhlc1736842021-11-23 12:38:51 +0000377
378 /// Convert this synchronous binder handle into an asynchronous one.
379 pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
380 where
381 I: ToAsyncInterface<P>,
382 {
383 // By implementing the ToAsyncInterface trait, it is guaranteed that the binder
384 // object is also valid for the target type.
385 FromIBinder::try_from(self.0.as_binder()).unwrap()
386 }
387
388 /// Convert this asynchronous binder handle into a synchronous one.
389 pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
390 where
391 I: ToSyncInterface,
392 {
393 // By implementing the ToSyncInterface trait, it is guaranteed that the binder
394 // object is also valid for the target type.
395 FromIBinder::try_from(self.0.as_binder()).unwrap()
396 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800397}
398
399impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
400 fn clone(&self) -> Self {
401 // Since we hold a strong reference, we should always be able to create
402 // a new strong reference to the same interface type, so try_from()
403 // should never fail here.
404 FromIBinder::try_from(self.0.as_binder()).unwrap()
405 }
406}
407
408impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
409 fn borrow(&self) -> &I {
410 &self.0
411 }
412}
413
414impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
415 fn as_ref(&self) -> &I {
416 &self.0
417 }
418}
419
420impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
421 type Target = I;
422
423 fn deref(&self) -> &Self::Target {
424 &self.0
425 }
426}
427
428impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
429 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
430 fmt::Debug::fmt(&**self, f)
431 }
432}
433
434impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
435 fn cmp(&self, other: &Self) -> Ordering {
436 self.0.as_binder().cmp(&other.0.as_binder())
437 }
438}
439
440impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
441 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Charisee Chiwad1b27c2023-10-12 16:02:39 -0700442 Some(self.cmp(other))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800443 }
444}
445
446impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
447 fn eq(&self, other: &Self) -> bool {
448 self.0.as_binder().eq(&other.0.as_binder())
449 }
450}
451
452impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
453
454/// Weak reference to a binder object
455#[derive(Debug)]
456pub struct Weak<I: FromIBinder + ?Sized> {
457 weak_binder: WpIBinder,
458 interface_type: PhantomData<I>,
459}
460
461impl<I: FromIBinder + ?Sized> Weak<I> {
462 /// Construct a new weak reference from a strong reference
463 fn new(binder: &Strong<I>) -> Self {
464 let weak_binder = binder.as_binder().downgrade();
Matthew Maurere268a9f2022-07-26 09:31:30 -0700465 Weak { weak_binder, interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800466 }
467
468 /// Upgrade this weak reference to a strong reference if the binder object
469 /// is still alive
470 pub fn upgrade(&self) -> Result<Strong<I>> {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700471 self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from)
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800472 }
473}
474
475impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
476 fn clone(&self) -> Self {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700477 Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800478 }
479}
480
481impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
482 fn cmp(&self, other: &Self) -> Ordering {
483 self.weak_binder.cmp(&other.weak_binder)
484 }
485}
486
487impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
488 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Charisee Chiwad1b27c2023-10-12 16:02:39 -0700489 Some(self.cmp(other))
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800490 }
491}
492
493impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
494 fn eq(&self, other: &Self) -> bool {
495 self.weak_binder == other.weak_binder
496 }
497}
498
499impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
500
Stephen Crane2a3c2502020-06-16 17:48:35 -0700501/// Create a function implementing a static getter for an interface class.
502///
503/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
504/// [`Interface`]) must have global, static class that uniquely identifies
505/// it. This macro implements an [`InterfaceClass`] getter to simplify these
506/// implementations.
507///
508/// The type of a structure that implements [`InterfaceClassMethods`] must be
509/// passed to this macro. For local services, this should be `Binder<Self>`
510/// since [`Binder`] implements [`InterfaceClassMethods`].
511///
512/// # Examples
513///
514/// When implementing a local [`Remotable`] service `ExampleService`, the
515/// `get_class` method is required in the [`Remotable`] impl block. This macro
516/// should be used as follows to implement this functionality:
517///
518/// ```rust
519/// impl Remotable for ExampleService {
520/// fn get_descriptor() -> &'static str {
521/// "android.os.IExampleInterface"
522/// }
523///
524/// fn on_transact(
525/// &self,
526/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000527/// data: &BorrowedParcel,
528/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700529/// ) -> Result<()> {
530/// // ...
531/// }
532///
533/// binder_fn_get_class!(Binder<Self>);
534/// }
535/// ```
536macro_rules! binder_fn_get_class {
537 ($class:ty) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000538 binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700539 };
540
541 ($constructor:expr) => {
Stephen Cranef2735b42022-01-19 17:49:46 +0000542 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700543 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000544 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700545
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100546 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
547 // variable, and therefore is thread-safe, as it can only occur
548 // once.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700549 CLASS_INIT.call_once(|| unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700550 CLASS = Some($constructor);
551 });
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100552 // Safety: The `CLASS` variable can only be mutated once, above, and
553 // is subsequently safe to read from any thread.
554 unsafe { CLASS.unwrap() }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700555 }
556 };
557}
558
559pub trait InterfaceClassMethods {
560 /// Get the interface descriptor string for this object type.
561 fn get_descriptor() -> &'static str
562 where
563 Self: Sized;
564
565 /// Called during construction of a new `AIBinder` object of this interface
566 /// class.
567 ///
568 /// The opaque pointer parameter will be the parameter provided to
569 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
570 /// `AIBinder` object.
571 ///
572 /// # Safety
573 ///
574 /// Callback called from C++. The parameter argument provided to
575 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
576 /// will take ownership of the returned pointer, which it will free via
577 /// `on_destroy`.
578 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
579
580 /// Called when a transaction needs to be processed by the local service
581 /// implementation.
582 ///
583 /// # Safety
584 ///
585 /// Callback called from C++. The `binder` parameter must be a valid pointer
586 /// to a binder object of this class with userdata initialized via this
587 /// class's `on_create`. The parcel parameters must be valid pointers to
588 /// parcel objects.
589 unsafe extern "C" fn on_transact(
590 binder: *mut sys::AIBinder,
591 code: u32,
592 data: *const sys::AParcel,
593 reply: *mut sys::AParcel,
594 ) -> status_t;
595
596 /// Called whenever an `AIBinder` object is no longer referenced and needs
597 /// to be destroyed.
598 ///
599 /// # Safety
600 ///
601 /// Callback called from C++. The opaque pointer parameter must be the value
602 /// returned by `on_create` for this class. This function takes ownership of
603 /// the provided pointer and destroys it.
604 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700605
606 /// Called to handle the `dump` transaction.
607 ///
608 /// # Safety
609 ///
610 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
611 /// contains a `T` pointer in its user data. fd should be a non-owned file
612 /// descriptor, and args must be an array of null-terminated string
613 /// poiinters with length num_args.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700614 unsafe extern "C" fn on_dump(
615 binder: *mut sys::AIBinder,
616 fd: i32,
617 args: *mut *const c_char,
618 num_args: u32,
619 ) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700620}
621
622/// Interface for transforming a generic SpIBinder into a specific remote
623/// interface trait.
624///
625/// # Example
626///
627/// For Binder interface `IFoo`, the following implementation should be made:
628/// ```no_run
629/// # use binder::{FromIBinder, SpIBinder, Result};
630/// # trait IFoo {}
631/// impl FromIBinder for dyn IFoo {
632/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
633/// // ...
634/// # Err(binder::StatusCode::OK)
635/// }
636/// }
637/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800638pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700639 /// Try to interpret a generic Binder object as this interface.
640 ///
641 /// Returns a trait object for the `Self` interface if this object
642 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800643 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700644}
645
646/// Trait for transparent Rust wrappers around android C++ native types.
647///
648/// The pointer return by this trait's methods should be immediately passed to
649/// C++ and not stored by Rust. The pointer is valid only as long as the
650/// underlying C++ object is alive, so users must be careful to take this into
651/// account, as Rust cannot enforce this.
652///
653/// # Safety
654///
655/// For this trait to be a correct implementation, `T` must be a valid android
656/// C++ type. Since we cannot constrain this via the type system, this trait is
657/// marked as unsafe.
658pub unsafe trait AsNative<T> {
659 /// Return a pointer to the native version of `self`
660 fn as_native(&self) -> *const T;
661
662 /// Return a mutable pointer to the native version of `self`
663 fn as_native_mut(&mut self) -> *mut T;
664}
665
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100666// Safety: If V is a valid Android C++ type then we can either use that or a
667// null pointer.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700668unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
669 fn as_native(&self) -> *const T {
670 self.as_ref().map_or(ptr::null(), |v| v.as_native())
671 }
672
673 fn as_native_mut(&mut self) -> *mut T {
674 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
675 }
676}
677
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000678/// The features to enable when creating a native Binder.
679///
680/// This should always be initialised with a default value, e.g.:
681/// ```
682/// # use binder::BinderFeatures;
683/// BinderFeatures {
684/// set_requesting_sid: true,
685/// ..BinderFeatures::default(),
686/// }
687/// ```
688#[derive(Clone, Debug, Default, Eq, PartialEq)]
689pub struct BinderFeatures {
690 /// Indicates that the service intends to receive caller security contexts. This must be true
691 /// for `ThreadState::with_calling_sid` to work.
Janis Danisevskis1323d512021-11-09 07:48:08 -0800692 #[cfg(not(android_vndk))]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000693 pub set_requesting_sid: bool,
694 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
695 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
696 // expressions entirely.
697 #[doc(hidden)]
698 pub _non_exhaustive: (),
699}
700
Stephen Crane2a3c2502020-06-16 17:48:35 -0700701/// Declare typed interfaces for a binder object.
702///
703/// Given an interface trait and descriptor string, create a native and remote
704/// proxy wrapper for this interface. The native service object (`$native`)
705/// implements `Remotable` and will dispatch to the function `$on_transact` to
706/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
707/// objects for this interface and can optionally contain additional fields.
708///
709/// Assuming the interface trait is `Interface`, `$on_transact` function must
710/// have the following type:
711///
712/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000713/// # use binder::{Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700714/// # trait Placeholder {
715/// fn on_transact(
716/// service: &dyn Interface,
717/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000718/// data: &BorrowedParcel,
719/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700720/// ) -> binder::Result<()>;
721/// # }
722/// ```
723///
724/// # Examples
725///
726/// The following example declares the local service type `BnServiceManager` and
727/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
728/// proxy respectively) for the `IServiceManager` Binder interface. The
729/// interfaces will be identified by the descriptor string
730/// "android.os.IServiceManager". The local service will dispatch transactions
731/// using the provided function, `on_transact`.
732///
733/// ```
Alice Ryhl8618c482021-11-09 15:35:35 +0000734/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700735///
736/// pub trait IServiceManager: Interface {
737/// // remote methods...
738/// }
739///
740/// declare_binder_interface! {
741/// IServiceManager["android.os.IServiceManager"] {
742/// native: BnServiceManager(on_transact),
743/// proxy: BpServiceManager,
744/// }
745/// }
746///
747/// fn on_transact(
748/// service: &dyn IServiceManager,
749/// code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000750/// data: &BorrowedParcel,
751/// reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700752/// ) -> binder::Result<()> {
753/// // ...
754/// Ok(())
755/// }
756///
757/// impl IServiceManager for BpServiceManager {
758/// // parceling/unparceling code for the IServiceManager emitted here
759/// }
760///
761/// impl IServiceManager for Binder<BnServiceManager> {
762/// // Forward calls to local implementation
763/// }
764/// ```
765#[macro_export]
766macro_rules! declare_binder_interface {
767 {
768 $interface:path[$descriptor:expr] {
769 native: $native:ident($on_transact:path),
770 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000771 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700772 }
773 } => {
774 $crate::declare_binder_interface! {
775 $interface[$descriptor] {
776 native: $native($on_transact),
777 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000778 $(async: $async_interface,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000779 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800780 }
781 }
782 };
783
784 {
785 $interface:path[$descriptor:expr] {
786 native: $native:ident($on_transact:path),
787 proxy: $proxy:ident,
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000788 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800789 stability: $stability:expr,
790 }
791 } => {
792 $crate::declare_binder_interface! {
793 $interface[$descriptor] {
794 native: $native($on_transact),
795 proxy: $proxy {},
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000796 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800797 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700798 }
799 }
800 };
801
802 {
803 $interface:path[$descriptor:expr] {
804 native: $native:ident($on_transact:path),
805 proxy: $proxy:ident {
806 $($fname:ident: $fty:ty = $finit:expr),*
807 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000808 $(async: $async_interface:ident,)?
Stephen Crane2a3c2502020-06-16 17:48:35 -0700809 }
810 } => {
811 $crate::declare_binder_interface! {
812 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800813 native: $native($on_transact),
814 proxy: $proxy {
815 $($fname: $fty = $finit),*
816 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000817 $(async: $async_interface,)?
Stephen Cranef2735b42022-01-19 17:49:46 +0000818 stability: $crate::binder_impl::Stability::default(),
Stephen Craneff7f03a2021-02-25 16:04:22 -0800819 }
820 }
821 };
822
823 {
824 $interface:path[$descriptor:expr] {
825 native: $native:ident($on_transact:path),
826 proxy: $proxy:ident {
827 $($fname:ident: $fty:ty = $finit:expr),*
828 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000829 $(async: $async_interface:ident,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800830 stability: $stability:expr,
831 }
832 } => {
833 $crate::declare_binder_interface! {
834 $interface[$descriptor] {
Stephen Cranef2735b42022-01-19 17:49:46 +0000835 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700836 native: $native($on_transact),
Stephen Cranef2735b42022-01-19 17:49:46 +0000837 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700838 proxy: $proxy {
839 $($fname: $fty = $finit),*
840 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000841 $(async: $async_interface,)?
Stephen Craneff7f03a2021-02-25 16:04:22 -0800842 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700843 }
844 }
845 };
846
847 {
848 $interface:path[$descriptor:expr] {
849 @doc[$native_doc:expr]
850 native: $native:ident($on_transact:path),
851
852 @doc[$proxy_doc:expr]
853 proxy: $proxy:ident {
854 $($fname:ident: $fty:ty = $finit:expr),*
855 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800856
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000857 $( async: $async_interface:ident, )?
858
Stephen Craneff7f03a2021-02-25 16:04:22 -0800859 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700860 }
861 } => {
862 #[doc = $proxy_doc]
863 pub struct $proxy {
864 binder: $crate::SpIBinder,
865 $($fname: $fty,)*
866 }
867
868 impl $crate::Interface for $proxy {
869 fn as_binder(&self) -> $crate::SpIBinder {
870 self.binder.clone()
871 }
872 }
873
Stephen Cranef2735b42022-01-19 17:49:46 +0000874 impl $crate::binder_impl::Proxy for $proxy
Stephen Crane2a3c2502020-06-16 17:48:35 -0700875 where
876 $proxy: $interface,
877 {
878 fn get_descriptor() -> &'static str {
879 $descriptor
880 }
881
Stephen Cranef2735b42022-01-19 17:49:46 +0000882 fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> {
Stephen Crane669deb62020-09-10 17:31:39 -0700883 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700884 }
885 }
886
887 #[doc = $native_doc]
888 #[repr(transparent)]
889 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
890
891 impl $native {
892 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000893 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 +0000894 let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability);
Janis Danisevskis1323d512021-11-09 07:48:08 -0800895 #[cfg(not(android_vndk))]
Stephen Cranef2735b42022-01-19 17:49:46 +0000896 $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800897 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700898 }
Orlando Arbildod0880e82023-10-09 17:36:17 +0000899
900 /// Tries to downcast the interface to another type.
901 /// When receiving this object from a binder call, make sure that the object received is
902 /// a binder native object and that is of the right type for the Downcast:
903 ///
904 /// let binder = received_object.as_binder();
905 /// if !binder.is_remote() {
906 /// let binder_native: Binder<BnFoo> = binder.try_into()?;
907 /// let original_object = binder_native.downcast_binder::<MyFoo>();
908 /// // Check that returned type is not None before using it
909 /// }
910 ///
911 /// Handle the error cases instead of just calling `unwrap` or `expect` to prevent a
912 /// malicious caller to mount a Denial of Service attack.
913 pub fn downcast_binder<T: $interface>(&self) -> Option<&T> {
914 self.0.as_any().downcast_ref::<T>()
915 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700916 }
917
Stephen Cranef2735b42022-01-19 17:49:46 +0000918 impl $crate::binder_impl::Remotable for $native {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700919 fn get_descriptor() -> &'static str {
920 $descriptor
921 }
922
Stephen Cranef2735b42022-01-19 17:49:46 +0000923 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 -0700924 match $on_transact(&*self.0, code, data, reply) {
925 // The C++ backend converts UNEXPECTED_NULL into an exception
926 Err($crate::StatusCode::UNEXPECTED_NULL) => {
927 let status = $crate::Status::new_exception(
928 $crate::ExceptionCode::NULL_POINTER,
929 None,
930 );
931 reply.write(&status)
932 },
933 result => result
934 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700935 }
936
Stephen Cranef2735b42022-01-19 17:49:46 +0000937 fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700938 self.0.dump(file, args)
939 }
940
Stephen Cranef2735b42022-01-19 17:49:46 +0000941 fn get_class() -> $crate::binder_impl::InterfaceClass {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700942 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
Stephen Cranef2735b42022-01-19 17:49:46 +0000943 static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700944
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100945 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
946 // variable, and therefore is thread-safe, as it can only occur
947 // once.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700948 CLASS_INIT.call_once(|| unsafe {
Stephen Cranef2735b42022-01-19 17:49:46 +0000949 CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700950 });
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100951 // Safety: The `CLASS` variable can only be mutated once, above,
952 // and is subsequently safe to read from any thread.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700953 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700954 CLASS.unwrap()
955 }
956 }
957 }
958
959 impl $crate::FromIBinder for dyn $interface {
Stephen Cranef2735b42022-01-19 17:49:46 +0000960 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> {
961 use $crate::binder_impl::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700962
963 let existing_class = ibinder.get_class();
964 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +0000965 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
966 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Stephen Crane669deb62020-09-10 17:31:39 -0700967 {
968 // The binder object's descriptor string matches what we
969 // expect. We still need to treat this local or already
970 // associated object as remote, because we can't cast it
971 // into a Rust service object without a matching class
972 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +0000973 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700974 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700975 }
976
Stephen Cranef2735b42022-01-19 17:49:46 +0000977 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
978 let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
Stephen Crane669deb62020-09-10 17:31:39 -0700979 std::convert::TryFrom::try_from(ibinder.clone());
980 if let Ok(service) = service {
981 // We were able to associate with our expected class and
982 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800983 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700984 } else {
985 // Service is remote
Stephen Cranef2735b42022-01-19 17:49:46 +0000986 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700987 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000988 }
Stephen Crane669deb62020-09-10 17:31:39 -0700989
990 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700991 }
992 }
993
Stephen Cranef2735b42022-01-19 17:49:46 +0000994 impl $crate::binder_impl::Serialize for dyn $interface + '_
Stephen Crane2a3c2502020-06-16 17:48:35 -0700995 where
Stephen Craned58bce02020-07-07 12:26:02 -0700996 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700997 {
Stephen Cranef2735b42022-01-19 17:49:46 +0000998 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700999 let binder = $crate::Interface::as_binder(self);
1000 parcel.write(&binder)
1001 }
1002 }
1003
Stephen Cranef2735b42022-01-19 17:49:46 +00001004 impl $crate::binder_impl::SerializeOption for dyn $interface + '_ {
1005 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Stephen Crane2a3c2502020-06-16 17:48:35 -07001006 parcel.write(&this.map($crate::Interface::as_binder))
1007 }
1008 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -07001009
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001010 impl std::fmt::Debug for dyn $interface + '_ {
Andrei Homescu2e3c1472020-08-11 16:35:40 -07001011 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1012 f.pad(stringify!($interface))
1013 }
1014 }
Andrei Homescu64ebd132020-08-07 22:12:48 -07001015
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001016 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -07001017 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -08001018 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -07001019 fn to_owned(&self) -> Self::Owned {
1020 self.as_binder().into_interface()
1021 .expect(concat!("Error cloning interface ", stringify!($interface)))
1022 }
1023 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001024
1025 $(
1026 // Async interface trait implementations.
Orlando Arbildod0880e82023-10-09 17:36:17 +00001027 impl<P: $crate::BinderAsyncPool + 'static> $crate::FromIBinder for dyn $async_interface<P> {
Stephen Cranef2735b42022-01-19 17:49:46 +00001028 fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
1029 use $crate::binder_impl::AssociateClass;
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001030
1031 let existing_class = ibinder.get_class();
1032 if let Some(class) = existing_class {
Stephen Cranef2735b42022-01-19 17:49:46 +00001033 if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
1034 class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001035 {
1036 // The binder object's descriptor string matches what we
1037 // expect. We still need to treat this local or already
1038 // associated object as remote, because we can't cast it
1039 // into a Rust service object without a matching class
1040 // pointer.
Stephen Cranef2735b42022-01-19 17:49:46 +00001041 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001042 }
1043 }
1044
Stephen Cranef2735b42022-01-19 17:49:46 +00001045 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
Alice Ryhleed9ac12023-07-25 13:45:47 +00001046 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001047 }
1048
1049 Err($crate::StatusCode::BAD_TYPE.into())
1050 }
1051 }
1052
Orlando Arbildod0880e82023-10-09 17:36:17 +00001053 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
Stephen Cranef2735b42022-01-19 17:49:46 +00001054 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001055 let binder = $crate::Interface::as_binder(self);
1056 parcel.write(&binder)
1057 }
1058 }
1059
Orlando Arbildod0880e82023-10-09 17:36:17 +00001060 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
Stephen Cranef2735b42022-01-19 17:49:46 +00001061 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001062 parcel.write(&this.map($crate::Interface::as_binder))
1063 }
1064 }
1065
Orlando Arbildod0880e82023-10-09 17:36:17 +00001066 impl<P: $crate::BinderAsyncPool + 'static> std::fmt::Debug for dyn $async_interface<P> + '_ {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001067 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1068 f.pad(stringify!($async_interface))
1069 }
1070 }
1071
1072 /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
Orlando Arbildod0880e82023-10-09 17:36:17 +00001073 impl<P: $crate::BinderAsyncPool + 'static> std::borrow::ToOwned for dyn $async_interface<P> {
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001074 type Owned = $crate::Strong<dyn $async_interface<P>>;
1075 fn to_owned(&self) -> Self::Owned {
1076 self.as_binder().into_interface()
1077 .expect(concat!("Error cloning interface ", stringify!($async_interface)))
1078 }
1079 }
Alice Ryhlc1736842021-11-23 12:38:51 +00001080
Orlando Arbildod0880e82023-10-09 17:36:17 +00001081 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
Alice Ryhlc1736842021-11-23 12:38:51 +00001082 type Target = dyn $async_interface<P>;
1083 }
1084
Orlando Arbildod0880e82023-10-09 17:36:17 +00001085 impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
Alice Ryhlc1736842021-11-23 12:38:51 +00001086 type Target = dyn $interface;
1087 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +00001088 )?
Stephen Crane2a3c2502020-06-16 17:48:35 -07001089 };
1090}
Andrei Homescu00eca712020-09-09 18:57:40 -07001091
1092/// Declare an AIDL enumeration.
1093///
1094/// This is mainly used internally by the AIDL compiler.
1095#[macro_export]
1096macro_rules! declare_binder_enum {
1097 {
Stephen Crane7bca1052021-10-25 17:52:51 -07001098 $( #[$attr:meta] )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001099 $enum:ident : [$backing:ty; $size:expr] {
Jooyung Han70d92812022-03-18 15:29:54 +09001100 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
Andrei Homescu00eca712020-09-09 18:57:40 -07001101 }
1102 } => {
Stephen Crane7bca1052021-10-25 17:52:51 -07001103 $( #[$attr] )*
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001104 #[derive(Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001105 #[allow(missing_docs)]
Andrei Homescu00eca712020-09-09 18:57:40 -07001106 pub struct $enum(pub $backing);
1107 impl $enum {
Jooyung Han70d92812022-03-18 15:29:54 +09001108 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001109
1110 #[inline(always)]
Stephen Crane7bca1052021-10-25 17:52:51 -07001111 #[allow(missing_docs)]
Andrei Homescu7f38cf92021-06-29 23:55:43 +00001112 pub const fn enum_values() -> [Self; $size] {
1113 [$(Self::$name),*]
1114 }
Andrei Homescu00eca712020-09-09 18:57:40 -07001115 }
1116
Andrei Homescuc06cfc32022-09-30 02:46:27 +00001117 impl std::fmt::Debug for $enum {
1118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1119 match self.0 {
1120 $($value => f.write_str(stringify!($name)),)*
1121 _ => f.write_fmt(format_args!("{}", self.0))
1122 }
1123 }
1124 }
1125
Stephen Cranef2735b42022-01-19 17:49:46 +00001126 impl $crate::binder_impl::Serialize for $enum {
1127 fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001128 parcel.write(&self.0)
1129 }
1130 }
1131
Stephen Cranef2735b42022-01-19 17:49:46 +00001132 impl $crate::binder_impl::SerializeArray for $enum {
1133 fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001134 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
Stephen Cranef2735b42022-01-19 17:49:46 +00001135 <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel)
Andrei Homescu00eca712020-09-09 18:57:40 -07001136 }
1137 }
1138
Stephen Cranef2735b42022-01-19 17:49:46 +00001139 impl $crate::binder_impl::Deserialize for $enum {
Andrei Homescu2b802f72023-05-05 03:21:43 +00001140 type UninitType = Self;
1141 fn uninit() -> Self::UninitType { Self::UninitType::default() }
1142 fn from_init(value: Self) -> Self::UninitType { value }
1143
Stephen Cranef2735b42022-01-19 17:49:46 +00001144 fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001145 parcel.read().map(Self)
1146 }
1147 }
1148
Stephen Cranef2735b42022-01-19 17:49:46 +00001149 impl $crate::binder_impl::DeserializeArray for $enum {
1150 fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> {
Andrei Homescu00eca712020-09-09 18:57:40 -07001151 let v: Option<Vec<$backing>> =
Stephen Cranef2735b42022-01-19 17:49:46 +00001152 <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?;
Andrei Homescu00eca712020-09-09 18:57:40 -07001153 Ok(v.map(|v| v.into_iter().map(Self).collect()))
1154 }
1155 }
1156 };
1157}