blob: 41ceee5697f6e9b3351c25a4f14a1a4e1a00de1f [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};
Stephen Crane2a3c2502020-06-16 17:48:35 -070020use crate::parcel::Parcel;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080021use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
Stephen Crane2a3c2502020-06-16 17:48:35 -070022use crate::sys;
23
Stephen Craneddb3e6d2020-12-18 13:27:22 -080024use std::borrow::Borrow;
25use std::cmp::Ordering;
Stephen Crane669deb62020-09-10 17:31:39 -070026use std::ffi::{c_void, CStr, CString};
Stephen Craneddb3e6d2020-12-18 13:27:22 -080027use std::fmt;
Stephen Crane2a3297f2021-06-11 16:48:10 -070028use std::fs::File;
Stephen Craneddb3e6d2020-12-18 13:27:22 -080029use std::marker::PhantomData;
30use std::ops::Deref;
Stephen Crane669deb62020-09-10 17:31:39 -070031use std::os::raw::c_char;
Stephen Crane2a3c2502020-06-16 17:48:35 -070032use std::os::unix::io::AsRawFd;
33use std::ptr;
34
35/// Binder action to perform.
36///
Andrew Walbran12400d82021-03-04 17:04:34 +000037/// This must be a number between [`FIRST_CALL_TRANSACTION`] and
38/// [`LAST_CALL_TRANSACTION`].
Stephen Crane2a3c2502020-06-16 17:48:35 -070039pub type TransactionCode = u32;
40
41/// Additional operation flags.
42///
Andrew Walbran12400d82021-03-04 17:04:34 +000043/// `FLAG_*` values.
Stephen Crane2a3c2502020-06-16 17:48:35 -070044pub type TransactionFlags = u32;
45
46/// Super-trait for Binder interfaces.
47///
48/// This trait allows conversion of a Binder interface trait object into an
49/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
50/// interfaces) must implement this trait.
51///
52/// This is equivalent `IInterface` in C++.
Stephen Cranef03fe3d2021-06-25 15:05:00 -070053pub trait Interface: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070054 /// Convert this binder object into a generic [`SpIBinder`] reference.
55 fn as_binder(&self) -> SpIBinder {
56 panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
57 }
Stephen Crane2a3297f2021-06-11 16:48:10 -070058
59 /// Dump transaction handler for this Binder object.
60 ///
61 /// This handler is a no-op by default and should be implemented for each
62 /// Binder service struct that wishes to respond to dump transactions.
63 fn dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
64 Ok(())
65 }
Stephen Crane2a3c2502020-06-16 17:48:35 -070066}
67
Stephen Craneff7f03a2021-02-25 16:04:22 -080068/// Interface stability promise
69///
70/// An interface can promise to be a stable vendor interface ([`Vintf`]), or
71/// makes no stability guarantees ([`Local`]). [`Local`] is
72/// currently the default stability.
73pub enum Stability {
74 /// Default stability, visible to other modules in the same compilation
75 /// context (e.g. modules on system.img)
76 Local,
77
78 /// A Vendor Interface Object, which promises to be stable
79 Vintf,
80}
81
82impl Default for Stability {
83 fn default() -> Self {
84 Stability::Local
85 }
86}
87
Stephen Crane2a3c2502020-06-16 17:48:35 -070088/// A local service that can be remotable via Binder.
89///
90/// An object that implement this interface made be made into a Binder service
91/// via `Binder::new(object)`.
92///
93/// This is a low-level interface that should normally be automatically
94/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
95/// the AIDL backend, users need only implement the high-level AIDL-defined
96/// interface. The AIDL compiler then generates a container struct that wraps
97/// the user-defined service and implements `Remotable`.
Andrei Homescu2c674b02020-08-07 22:12:27 -070098pub trait Remotable: Send + Sync {
Stephen Crane2a3c2502020-06-16 17:48:35 -070099 /// The Binder interface descriptor string.
100 ///
101 /// This string is a unique identifier for a Binder interface, and should be
102 /// the same between all implementations of that interface.
103 fn get_descriptor() -> &'static str;
104
105 /// Handle and reply to a request to invoke a transaction on this object.
106 ///
107 /// `reply` may be [`None`] if the sender does not expect a reply.
108 fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
109
Stephen Crane2a3297f2021-06-11 16:48:10 -0700110 /// Handle a request to invoke the dump transaction on this
111 /// object.
112 fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>;
113
Stephen Crane2a3c2502020-06-16 17:48:35 -0700114 /// Retrieve the class of this remote object.
115 ///
116 /// This method should always return the same InterfaceClass for the same
117 /// type.
118 fn get_class() -> InterfaceClass;
119}
120
Andrew Walbran12400d82021-03-04 17:04:34 +0000121/// First transaction code available for user commands (inclusive)
122pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
123/// Last transaction code available for user commands (inclusive)
124pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
125
126/// Corresponds to TF_ONE_WAY -- an asynchronous call.
127pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
128/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
129pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
Stephen Craneff7f03a2021-02-25 16:04:22 -0800130/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
131pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
Andrew Walbran12400d82021-03-04 17:04:34 +0000132
133/// Internal interface of binder local or remote objects for making
134/// transactions.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700135///
Andrew Walbran12400d82021-03-04 17:04:34 +0000136/// This trait corresponds to the parts of the interface of the C++ `IBinder`
137/// class which are internal implementation details.
138pub trait IBinderInternal: IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700139 /// Is this object still alive?
140 fn is_binder_alive(&self) -> bool;
141
142 /// Send a ping transaction to this object
143 fn ping_binder(&mut self) -> Result<()>;
144
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700145 /// Indicate that the service intends to receive caller security contexts.
146 fn set_requesting_sid(&mut self, enable: bool);
147
Stephen Crane2a3c2502020-06-16 17:48:35 -0700148 /// Dump this object to the given file handle
149 fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
150
151 /// Get a new interface that exposes additional extension functionality, if
152 /// available.
153 fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
154
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000155 /// Create a Parcel that can be used with `submit_transact`.
156 fn prepare_transact(&self) -> Result<Parcel>;
157
Stephen Crane2a3c2502020-06-16 17:48:35 -0700158 /// Perform a generic operation with the object.
159 ///
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000160 /// The provided [`Parcel`] must have been created by a call to
161 /// `prepare_transact` on the same binder.
162 ///
163 /// # Arguments
164 ///
165 /// * `code` - Transaction code for the operation.
166 /// * `data` - [`Parcel`] with input data.
167 /// * `flags` - Transaction flags, e.g. marking the transaction as
168 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
169 fn submit_transact(
170 &self,
171 code: TransactionCode,
172 data: Parcel,
173 flags: TransactionFlags,
174 ) -> Result<Parcel>;
175
176 /// Perform a generic operation with the object. This is a convenience
177 /// method that internally calls `prepare_transact` followed by
178 /// `submit_transact.
179 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700180 /// # Arguments
181 /// * `code` - Transaction code for the operation
Stephen Crane2a3c2502020-06-16 17:48:35 -0700182 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000183 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000184 /// * `input_callback` A callback for building the `Parcel`.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700185 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
186 &self,
187 code: TransactionCode,
188 flags: TransactionFlags,
189 input_callback: F,
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000190 ) -> Result<Parcel> {
191 let mut parcel = self.prepare_transact()?;
192 input_callback(&mut parcel)?;
193 self.submit_transact(code, parcel, flags)
194 }
Andrew Walbran12400d82021-03-04 17:04:34 +0000195}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700196
Andrew Walbran12400d82021-03-04 17:04:34 +0000197/// Interface of binder local or remote objects.
198///
199/// This trait corresponds to the parts of the interface of the C++ `IBinder`
200/// class which are public.
201pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700202 /// Register the recipient for a notification if this binder
203 /// goes away. If this binder object unexpectedly goes away
204 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000205 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700206 ///
207 /// You will only receive death notifications for remote binders,
208 /// as local binders by definition can't die without you dying as well.
209 /// Trying to use this function on a local binder will result in an
210 /// INVALID_OPERATION code being returned and nothing happening.
211 ///
212 /// This link always holds a weak reference to its recipient.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700213 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
214
215 /// Remove a previously registered death notification.
216 /// The recipient will no longer be called if this object
217 /// dies.
218 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
219}
220
221/// Opaque reference to the type of a Binder interface.
222///
223/// This object encapsulates the Binder interface descriptor string, along with
224/// the binder transaction callback, if the class describes a local service.
225///
226/// A Binder remotable object may only have a single interface class, and any
227/// given object can only be associated with one class. Two objects with
228/// different classes are incompatible, even if both classes have the same
229/// interface descriptor.
230#[derive(Copy, Clone, PartialEq, Eq)]
231pub struct InterfaceClass(*const sys::AIBinder_Class);
232
233impl InterfaceClass {
234 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
235 ///
236 /// Note: the returned pointer will not be constant. Calling this method
237 /// multiple times for the same type will result in distinct class
238 /// pointers. A static getter for this value is implemented in
239 /// [`declare_binder_interface!`].
240 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
241 let descriptor = CString::new(I::get_descriptor()).unwrap();
242 let ptr = unsafe {
243 // Safety: `AIBinder_Class_define` expects a valid C string, and
244 // three valid callback functions, all non-null pointers. The C
245 // string is copied and need not be valid for longer than the call,
246 // so we can drop it after the call. We can safely assign null to
247 // the onDump and handleShellCommand callbacks as long as the class
248 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
249 // be a NULL pointer. Rust retains ownership of the pointer after it
250 // is defined.
251 let class = sys::AIBinder_Class_define(
252 descriptor.as_ptr(),
253 Some(I::on_create),
254 Some(I::on_destroy),
255 Some(I::on_transact),
256 );
257 if class.is_null() {
258 panic!("Expected non-null class pointer from AIBinder_Class_define!");
259 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700260 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700261 sys::AIBinder_Class_setHandleShellCommand(class, None);
262 class
263 };
264 InterfaceClass(ptr)
265 }
266
267 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
268 /// pointer.
269 ///
270 /// # Safety
271 ///
272 /// This function is safe iff `ptr` is a valid, non-null pointer to an
273 /// `AIBinder_Class`.
274 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
275 InterfaceClass(ptr)
276 }
Stephen Crane669deb62020-09-10 17:31:39 -0700277
278 /// Get the interface descriptor string of this class.
279 pub fn get_descriptor(&self) -> String {
280 unsafe {
281 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
282 // is always a two-byte null terminated sequence of u16s. Thus, we
283 // can continue reading from the pointer until we hit a null value,
284 // and this pointer can be a valid slice if the slice length is <=
285 // the number of u16 elements before the null terminator.
286
287 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000288 CStr::from_ptr(raw_descriptor)
289 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700290 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
291 .into()
292 }
293 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700294}
295
296impl From<InterfaceClass> for *const sys::AIBinder_Class {
297 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
298 class.0
299 }
300}
301
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800302/// Strong reference to a binder object
303pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
304
305impl<I: FromIBinder + ?Sized> Strong<I> {
306 /// Create a new strong reference to the provided binder object
307 pub fn new(binder: Box<I>) -> Self {
308 Self(binder)
309 }
310
311 /// Construct a new weak reference to this binder
312 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
313 Weak::new(this)
314 }
315}
316
317impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
318 fn clone(&self) -> Self {
319 // Since we hold a strong reference, we should always be able to create
320 // a new strong reference to the same interface type, so try_from()
321 // should never fail here.
322 FromIBinder::try_from(self.0.as_binder()).unwrap()
323 }
324}
325
326impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
327 fn borrow(&self) -> &I {
328 &self.0
329 }
330}
331
332impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
333 fn as_ref(&self) -> &I {
334 &self.0
335 }
336}
337
338impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
339 type Target = I;
340
341 fn deref(&self) -> &Self::Target {
342 &self.0
343 }
344}
345
346impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348 fmt::Debug::fmt(&**self, f)
349 }
350}
351
352impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
353 fn cmp(&self, other: &Self) -> Ordering {
354 self.0.as_binder().cmp(&other.0.as_binder())
355 }
356}
357
358impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
359 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
360 self.0.as_binder().partial_cmp(&other.0.as_binder())
361 }
362}
363
364impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
365 fn eq(&self, other: &Self) -> bool {
366 self.0.as_binder().eq(&other.0.as_binder())
367 }
368}
369
370impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
371
372/// Weak reference to a binder object
373#[derive(Debug)]
374pub struct Weak<I: FromIBinder + ?Sized> {
375 weak_binder: WpIBinder,
376 interface_type: PhantomData<I>,
377}
378
379impl<I: FromIBinder + ?Sized> Weak<I> {
380 /// Construct a new weak reference from a strong reference
381 fn new(binder: &Strong<I>) -> Self {
382 let weak_binder = binder.as_binder().downgrade();
383 Weak {
384 weak_binder,
385 interface_type: PhantomData,
386 }
387 }
388
389 /// Upgrade this weak reference to a strong reference if the binder object
390 /// is still alive
391 pub fn upgrade(&self) -> Result<Strong<I>> {
392 self.weak_binder
393 .promote()
394 .ok_or(StatusCode::DEAD_OBJECT)
395 .and_then(FromIBinder::try_from)
396 }
397}
398
399impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
400 fn clone(&self) -> Self {
401 Self {
402 weak_binder: self.weak_binder.clone(),
403 interface_type: PhantomData,
404 }
405 }
406}
407
408impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
409 fn cmp(&self, other: &Self) -> Ordering {
410 self.weak_binder.cmp(&other.weak_binder)
411 }
412}
413
414impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
415 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
416 self.weak_binder.partial_cmp(&other.weak_binder)
417 }
418}
419
420impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
421 fn eq(&self, other: &Self) -> bool {
422 self.weak_binder == other.weak_binder
423 }
424}
425
426impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
427
Stephen Crane2a3c2502020-06-16 17:48:35 -0700428/// Create a function implementing a static getter for an interface class.
429///
430/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
431/// [`Interface`]) must have global, static class that uniquely identifies
432/// it. This macro implements an [`InterfaceClass`] getter to simplify these
433/// implementations.
434///
435/// The type of a structure that implements [`InterfaceClassMethods`] must be
436/// passed to this macro. For local services, this should be `Binder<Self>`
437/// since [`Binder`] implements [`InterfaceClassMethods`].
438///
439/// # Examples
440///
441/// When implementing a local [`Remotable`] service `ExampleService`, the
442/// `get_class` method is required in the [`Remotable`] impl block. This macro
443/// should be used as follows to implement this functionality:
444///
445/// ```rust
446/// impl Remotable for ExampleService {
447/// fn get_descriptor() -> &'static str {
448/// "android.os.IExampleInterface"
449/// }
450///
451/// fn on_transact(
452/// &self,
453/// code: TransactionCode,
454/// data: &Parcel,
455/// reply: &mut Parcel,
456/// ) -> Result<()> {
457/// // ...
458/// }
459///
460/// binder_fn_get_class!(Binder<Self>);
461/// }
462/// ```
463macro_rules! binder_fn_get_class {
464 ($class:ty) => {
465 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
466 };
467
468 ($constructor:expr) => {
469 fn get_class() -> $crate::InterfaceClass {
470 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
471 static mut CLASS: Option<$crate::InterfaceClass> = None;
472
473 CLASS_INIT.call_once(|| unsafe {
474 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
475 // variable, and therefore is thread-safe, as it can only occur
476 // once.
477 CLASS = Some($constructor);
478 });
479 unsafe {
480 // Safety: The `CLASS` variable can only be mutated once, above,
481 // and is subsequently safe to read from any thread.
482 CLASS.unwrap()
483 }
484 }
485 };
486}
487
488pub trait InterfaceClassMethods {
489 /// Get the interface descriptor string for this object type.
490 fn get_descriptor() -> &'static str
491 where
492 Self: Sized;
493
494 /// Called during construction of a new `AIBinder` object of this interface
495 /// class.
496 ///
497 /// The opaque pointer parameter will be the parameter provided to
498 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
499 /// `AIBinder` object.
500 ///
501 /// # Safety
502 ///
503 /// Callback called from C++. The parameter argument provided to
504 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
505 /// will take ownership of the returned pointer, which it will free via
506 /// `on_destroy`.
507 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
508
509 /// Called when a transaction needs to be processed by the local service
510 /// implementation.
511 ///
512 /// # Safety
513 ///
514 /// Callback called from C++. The `binder` parameter must be a valid pointer
515 /// to a binder object of this class with userdata initialized via this
516 /// class's `on_create`. The parcel parameters must be valid pointers to
517 /// parcel objects.
518 unsafe extern "C" fn on_transact(
519 binder: *mut sys::AIBinder,
520 code: u32,
521 data: *const sys::AParcel,
522 reply: *mut sys::AParcel,
523 ) -> status_t;
524
525 /// Called whenever an `AIBinder` object is no longer referenced and needs
526 /// to be destroyed.
527 ///
528 /// # Safety
529 ///
530 /// Callback called from C++. The opaque pointer parameter must be the value
531 /// returned by `on_create` for this class. This function takes ownership of
532 /// the provided pointer and destroys it.
533 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700534
535 /// Called to handle the `dump` transaction.
536 ///
537 /// # Safety
538 ///
539 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
540 /// contains a `T` pointer in its user data. fd should be a non-owned file
541 /// descriptor, and args must be an array of null-terminated string
542 /// poiinters with length num_args.
543 unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700544}
545
546/// Interface for transforming a generic SpIBinder into a specific remote
547/// interface trait.
548///
549/// # Example
550///
551/// For Binder interface `IFoo`, the following implementation should be made:
552/// ```no_run
553/// # use binder::{FromIBinder, SpIBinder, Result};
554/// # trait IFoo {}
555/// impl FromIBinder for dyn IFoo {
556/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
557/// // ...
558/// # Err(binder::StatusCode::OK)
559/// }
560/// }
561/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800562pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700563 /// Try to interpret a generic Binder object as this interface.
564 ///
565 /// Returns a trait object for the `Self` interface if this object
566 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800567 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700568}
569
570/// Trait for transparent Rust wrappers around android C++ native types.
571///
572/// The pointer return by this trait's methods should be immediately passed to
573/// C++ and not stored by Rust. The pointer is valid only as long as the
574/// underlying C++ object is alive, so users must be careful to take this into
575/// account, as Rust cannot enforce this.
576///
577/// # Safety
578///
579/// For this trait to be a correct implementation, `T` must be a valid android
580/// C++ type. Since we cannot constrain this via the type system, this trait is
581/// marked as unsafe.
582pub unsafe trait AsNative<T> {
583 /// Return a pointer to the native version of `self`
584 fn as_native(&self) -> *const T;
585
586 /// Return a mutable pointer to the native version of `self`
587 fn as_native_mut(&mut self) -> *mut T;
588}
589
590unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
591 fn as_native(&self) -> *const T {
592 self.as_ref().map_or(ptr::null(), |v| v.as_native())
593 }
594
595 fn as_native_mut(&mut self) -> *mut T {
596 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
597 }
598}
599
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000600/// The features to enable when creating a native Binder.
601///
602/// This should always be initialised with a default value, e.g.:
603/// ```
604/// # use binder::BinderFeatures;
605/// BinderFeatures {
606/// set_requesting_sid: true,
607/// ..BinderFeatures::default(),
608/// }
609/// ```
610#[derive(Clone, Debug, Default, Eq, PartialEq)]
611pub struct BinderFeatures {
612 /// Indicates that the service intends to receive caller security contexts. This must be true
613 /// for `ThreadState::with_calling_sid` to work.
614 pub set_requesting_sid: bool,
615 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
616 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
617 // expressions entirely.
618 #[doc(hidden)]
619 pub _non_exhaustive: (),
620}
621
Stephen Crane2a3c2502020-06-16 17:48:35 -0700622/// Declare typed interfaces for a binder object.
623///
624/// Given an interface trait and descriptor string, create a native and remote
625/// proxy wrapper for this interface. The native service object (`$native`)
626/// implements `Remotable` and will dispatch to the function `$on_transact` to
627/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
628/// objects for this interface and can optionally contain additional fields.
629///
630/// Assuming the interface trait is `Interface`, `$on_transact` function must
631/// have the following type:
632///
633/// ```
634/// # use binder::{Interface, TransactionCode, Parcel};
635/// # trait Placeholder {
636/// fn on_transact(
637/// service: &dyn Interface,
638/// code: TransactionCode,
639/// data: &Parcel,
640/// reply: &mut Parcel,
641/// ) -> binder::Result<()>;
642/// # }
643/// ```
644///
645/// # Examples
646///
647/// The following example declares the local service type `BnServiceManager` and
648/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
649/// proxy respectively) for the `IServiceManager` Binder interface. The
650/// interfaces will be identified by the descriptor string
651/// "android.os.IServiceManager". The local service will dispatch transactions
652/// using the provided function, `on_transact`.
653///
654/// ```
655/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
656///
657/// pub trait IServiceManager: Interface {
658/// // remote methods...
659/// }
660///
661/// declare_binder_interface! {
662/// IServiceManager["android.os.IServiceManager"] {
663/// native: BnServiceManager(on_transact),
664/// proxy: BpServiceManager,
665/// }
666/// }
667///
668/// fn on_transact(
669/// service: &dyn IServiceManager,
670/// code: TransactionCode,
671/// data: &Parcel,
672/// reply: &mut Parcel,
673/// ) -> binder::Result<()> {
674/// // ...
675/// Ok(())
676/// }
677///
678/// impl IServiceManager for BpServiceManager {
679/// // parceling/unparceling code for the IServiceManager emitted here
680/// }
681///
682/// impl IServiceManager for Binder<BnServiceManager> {
683/// // Forward calls to local implementation
684/// }
685/// ```
686#[macro_export]
687macro_rules! declare_binder_interface {
688 {
689 $interface:path[$descriptor:expr] {
690 native: $native:ident($on_transact:path),
691 proxy: $proxy:ident,
692 }
693 } => {
694 $crate::declare_binder_interface! {
695 $interface[$descriptor] {
696 native: $native($on_transact),
697 proxy: $proxy {},
Stephen Craneff7f03a2021-02-25 16:04:22 -0800698 stability: $crate::Stability::default(),
699 }
700 }
701 };
702
703 {
704 $interface:path[$descriptor:expr] {
705 native: $native:ident($on_transact:path),
706 proxy: $proxy:ident,
707 stability: $stability:expr,
708 }
709 } => {
710 $crate::declare_binder_interface! {
711 $interface[$descriptor] {
712 native: $native($on_transact),
713 proxy: $proxy {},
714 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700715 }
716 }
717 };
718
719 {
720 $interface:path[$descriptor:expr] {
721 native: $native:ident($on_transact:path),
722 proxy: $proxy:ident {
723 $($fname:ident: $fty:ty = $finit:expr),*
724 },
725 }
726 } => {
727 $crate::declare_binder_interface! {
728 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800729 native: $native($on_transact),
730 proxy: $proxy {
731 $($fname: $fty = $finit),*
732 },
733 stability: $crate::Stability::default(),
734 }
735 }
736 };
737
738 {
739 $interface:path[$descriptor:expr] {
740 native: $native:ident($on_transact:path),
741 proxy: $proxy:ident {
742 $($fname:ident: $fty:ty = $finit:expr),*
743 },
744 stability: $stability:expr,
745 }
746 } => {
747 $crate::declare_binder_interface! {
748 $interface[$descriptor] {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700749 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
750 native: $native($on_transact),
751 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
752 proxy: $proxy {
753 $($fname: $fty = $finit),*
754 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800755 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700756 }
757 }
758 };
759
760 {
761 $interface:path[$descriptor:expr] {
762 @doc[$native_doc:expr]
763 native: $native:ident($on_transact:path),
764
765 @doc[$proxy_doc:expr]
766 proxy: $proxy:ident {
767 $($fname:ident: $fty:ty = $finit:expr),*
768 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800769
770 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700771 }
772 } => {
773 #[doc = $proxy_doc]
774 pub struct $proxy {
775 binder: $crate::SpIBinder,
776 $($fname: $fty,)*
777 }
778
779 impl $crate::Interface for $proxy {
780 fn as_binder(&self) -> $crate::SpIBinder {
781 self.binder.clone()
782 }
783 }
784
785 impl $crate::Proxy for $proxy
786 where
787 $proxy: $interface,
788 {
789 fn get_descriptor() -> &'static str {
790 $descriptor
791 }
792
793 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700794 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700795 }
796 }
797
798 #[doc = $native_doc]
799 #[repr(transparent)]
800 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
801
802 impl $native {
803 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000804 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
805 let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
806 $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800807 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700808 }
809 }
810
811 impl $crate::Remotable for $native {
812 fn get_descriptor() -> &'static str {
813 $descriptor
814 }
815
816 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700817 match $on_transact(&*self.0, code, data, reply) {
818 // The C++ backend converts UNEXPECTED_NULL into an exception
819 Err($crate::StatusCode::UNEXPECTED_NULL) => {
820 let status = $crate::Status::new_exception(
821 $crate::ExceptionCode::NULL_POINTER,
822 None,
823 );
824 reply.write(&status)
825 },
826 result => result
827 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700828 }
829
Stephen Crane2a3297f2021-06-11 16:48:10 -0700830 fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> {
831 self.0.dump(file, args)
832 }
833
Stephen Crane2a3c2502020-06-16 17:48:35 -0700834 fn get_class() -> $crate::InterfaceClass {
835 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
836 static mut CLASS: Option<$crate::InterfaceClass> = None;
837
838 CLASS_INIT.call_once(|| unsafe {
839 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
840 // variable, and therefore is thread-safe, as it can only occur
841 // once.
842 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
843 });
844 unsafe {
845 // Safety: The `CLASS` variable can only be mutated once, above,
846 // and is subsequently safe to read from any thread.
847 CLASS.unwrap()
848 }
849 }
850 }
851
852 impl $crate::FromIBinder for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800853 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700854 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700855
856 let existing_class = ibinder.get_class();
857 if let Some(class) = existing_class {
858 if class != <$native as $crate::Remotable>::get_class() &&
859 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
860 {
861 // The binder object's descriptor string matches what we
862 // expect. We still need to treat this local or already
863 // associated object as remote, because we can't cast it
864 // into a Rust service object without a matching class
865 // pointer.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800866 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700867 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700868 }
869
Stephen Crane669deb62020-09-10 17:31:39 -0700870 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
871 let service: $crate::Result<$crate::Binder<$native>> =
872 std::convert::TryFrom::try_from(ibinder.clone());
873 if let Ok(service) = service {
874 // We were able to associate with our expected class and
875 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800876 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700877 } else {
878 // Service is remote
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800879 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700880 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000881 }
Stephen Crane669deb62020-09-10 17:31:39 -0700882
883 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700884 }
885 }
886
887 impl $crate::parcel::Serialize for dyn $interface + '_
888 where
Stephen Craned58bce02020-07-07 12:26:02 -0700889 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700890 {
891 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
892 let binder = $crate::Interface::as_binder(self);
893 parcel.write(&binder)
894 }
895 }
896
897 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
898 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
899 parcel.write(&this.map($crate::Interface::as_binder))
900 }
901 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700902
903 impl std::fmt::Debug for dyn $interface {
904 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
905 f.pad(stringify!($interface))
906 }
907 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700908
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800909 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700910 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800911 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700912 fn to_owned(&self) -> Self::Owned {
913 self.as_binder().into_interface()
914 .expect(concat!("Error cloning interface ", stringify!($interface)))
915 }
916 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700917 };
918}
Andrei Homescu00eca712020-09-09 18:57:40 -0700919
920/// Declare an AIDL enumeration.
921///
922/// This is mainly used internally by the AIDL compiler.
923#[macro_export]
924macro_rules! declare_binder_enum {
925 {
Andrei Homescu7f38cf92021-06-29 23:55:43 +0000926 $enum:ident : [$backing:ty; $size:expr] {
Andrei Homescu00eca712020-09-09 18:57:40 -0700927 $( $name:ident = $value:expr, )*
928 }
929 } => {
930 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
931 pub struct $enum(pub $backing);
932 impl $enum {
933 $( pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +0000934
935 #[inline(always)]
936 pub const fn enum_values() -> [Self; $size] {
937 [$(Self::$name),*]
938 }
Andrei Homescu00eca712020-09-09 18:57:40 -0700939 }
940
941 impl $crate::parcel::Serialize for $enum {
942 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
943 parcel.write(&self.0)
944 }
945 }
946
947 impl $crate::parcel::SerializeArray for $enum {
948 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
949 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
950 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
951 }
952 }
953
954 impl $crate::parcel::Deserialize for $enum {
955 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
956 parcel.read().map(Self)
957 }
958 }
959
960 impl $crate::parcel::DeserializeArray for $enum {
961 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
962 let v: Option<Vec<$backing>> =
963 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
964 Ok(v.map(|v| v.into_iter().map(Self).collect()))
965 }
966 }
967 };
968}