blob: dd0c7b82e0092e53afb840b73ae3117183e149a4 [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
155 /// Perform a generic operation with the object.
156 ///
157 /// # Arguments
158 /// * `code` - Transaction code for the operation
159 /// * `data` - [`Parcel`] with input data
160 /// * `reply` - Optional [`Parcel`] for reply data
161 /// * `flags` - Transaction flags, e.g. marking the transaction as
Andrew Walbran12400d82021-03-04 17:04:34 +0000162 /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700163 fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
164 &self,
165 code: TransactionCode,
166 flags: TransactionFlags,
167 input_callback: F,
168 ) -> Result<Parcel>;
Andrew Walbran12400d82021-03-04 17:04:34 +0000169}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700170
Andrew Walbran12400d82021-03-04 17:04:34 +0000171/// Interface of binder local or remote objects.
172///
173/// This trait corresponds to the parts of the interface of the C++ `IBinder`
174/// class which are public.
175pub trait IBinder {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700176 /// Register the recipient for a notification if this binder
177 /// goes away. If this binder object unexpectedly goes away
178 /// (typically because its hosting process has been killed),
Andrew Walbran12400d82021-03-04 17:04:34 +0000179 /// then the `DeathRecipient`'s callback will be called.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700180 ///
181 /// You will only receive death notifications for remote binders,
182 /// as local binders by definition can't die without you dying as well.
183 /// Trying to use this function on a local binder will result in an
184 /// INVALID_OPERATION code being returned and nothing happening.
185 ///
186 /// This link always holds a weak reference to its recipient.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700187 fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
188
189 /// Remove a previously registered death notification.
190 /// The recipient will no longer be called if this object
191 /// dies.
192 fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
193}
194
195/// Opaque reference to the type of a Binder interface.
196///
197/// This object encapsulates the Binder interface descriptor string, along with
198/// the binder transaction callback, if the class describes a local service.
199///
200/// A Binder remotable object may only have a single interface class, and any
201/// given object can only be associated with one class. Two objects with
202/// different classes are incompatible, even if both classes have the same
203/// interface descriptor.
204#[derive(Copy, Clone, PartialEq, Eq)]
205pub struct InterfaceClass(*const sys::AIBinder_Class);
206
207impl InterfaceClass {
208 /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
209 ///
210 /// Note: the returned pointer will not be constant. Calling this method
211 /// multiple times for the same type will result in distinct class
212 /// pointers. A static getter for this value is implemented in
213 /// [`declare_binder_interface!`].
214 pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
215 let descriptor = CString::new(I::get_descriptor()).unwrap();
216 let ptr = unsafe {
217 // Safety: `AIBinder_Class_define` expects a valid C string, and
218 // three valid callback functions, all non-null pointers. The C
219 // string is copied and need not be valid for longer than the call,
220 // so we can drop it after the call. We can safely assign null to
221 // the onDump and handleShellCommand callbacks as long as the class
222 // pointer was non-null. Rust None for a Option<fn> is guaranteed to
223 // be a NULL pointer. Rust retains ownership of the pointer after it
224 // is defined.
225 let class = sys::AIBinder_Class_define(
226 descriptor.as_ptr(),
227 Some(I::on_create),
228 Some(I::on_destroy),
229 Some(I::on_transact),
230 );
231 if class.is_null() {
232 panic!("Expected non-null class pointer from AIBinder_Class_define!");
233 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700234 sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700235 sys::AIBinder_Class_setHandleShellCommand(class, None);
236 class
237 };
238 InterfaceClass(ptr)
239 }
240
241 /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
242 /// pointer.
243 ///
244 /// # Safety
245 ///
246 /// This function is safe iff `ptr` is a valid, non-null pointer to an
247 /// `AIBinder_Class`.
248 pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
249 InterfaceClass(ptr)
250 }
Stephen Crane669deb62020-09-10 17:31:39 -0700251
252 /// Get the interface descriptor string of this class.
253 pub fn get_descriptor(&self) -> String {
254 unsafe {
255 // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
256 // is always a two-byte null terminated sequence of u16s. Thus, we
257 // can continue reading from the pointer until we hit a null value,
258 // and this pointer can be a valid slice if the slice length is <=
259 // the number of u16 elements before the null terminator.
260
261 let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
Andrew Walbran12400d82021-03-04 17:04:34 +0000262 CStr::from_ptr(raw_descriptor)
263 .to_str()
Stephen Crane669deb62020-09-10 17:31:39 -0700264 .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
265 .into()
266 }
267 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700268}
269
270impl From<InterfaceClass> for *const sys::AIBinder_Class {
271 fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
272 class.0
273 }
274}
275
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800276/// Strong reference to a binder object
277pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
278
279impl<I: FromIBinder + ?Sized> Strong<I> {
280 /// Create a new strong reference to the provided binder object
281 pub fn new(binder: Box<I>) -> Self {
282 Self(binder)
283 }
284
285 /// Construct a new weak reference to this binder
286 pub fn downgrade(this: &Strong<I>) -> Weak<I> {
287 Weak::new(this)
288 }
289}
290
291impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
292 fn clone(&self) -> Self {
293 // Since we hold a strong reference, we should always be able to create
294 // a new strong reference to the same interface type, so try_from()
295 // should never fail here.
296 FromIBinder::try_from(self.0.as_binder()).unwrap()
297 }
298}
299
300impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
301 fn borrow(&self) -> &I {
302 &self.0
303 }
304}
305
306impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
307 fn as_ref(&self) -> &I {
308 &self.0
309 }
310}
311
312impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
313 type Target = I;
314
315 fn deref(&self) -> &Self::Target {
316 &self.0
317 }
318}
319
320impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
321 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
322 fmt::Debug::fmt(&**self, f)
323 }
324}
325
326impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
327 fn cmp(&self, other: &Self) -> Ordering {
328 self.0.as_binder().cmp(&other.0.as_binder())
329 }
330}
331
332impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
333 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
334 self.0.as_binder().partial_cmp(&other.0.as_binder())
335 }
336}
337
338impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
339 fn eq(&self, other: &Self) -> bool {
340 self.0.as_binder().eq(&other.0.as_binder())
341 }
342}
343
344impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
345
346/// Weak reference to a binder object
347#[derive(Debug)]
348pub struct Weak<I: FromIBinder + ?Sized> {
349 weak_binder: WpIBinder,
350 interface_type: PhantomData<I>,
351}
352
353impl<I: FromIBinder + ?Sized> Weak<I> {
354 /// Construct a new weak reference from a strong reference
355 fn new(binder: &Strong<I>) -> Self {
356 let weak_binder = binder.as_binder().downgrade();
357 Weak {
358 weak_binder,
359 interface_type: PhantomData,
360 }
361 }
362
363 /// Upgrade this weak reference to a strong reference if the binder object
364 /// is still alive
365 pub fn upgrade(&self) -> Result<Strong<I>> {
366 self.weak_binder
367 .promote()
368 .ok_or(StatusCode::DEAD_OBJECT)
369 .and_then(FromIBinder::try_from)
370 }
371}
372
373impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
374 fn clone(&self) -> Self {
375 Self {
376 weak_binder: self.weak_binder.clone(),
377 interface_type: PhantomData,
378 }
379 }
380}
381
382impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
383 fn cmp(&self, other: &Self) -> Ordering {
384 self.weak_binder.cmp(&other.weak_binder)
385 }
386}
387
388impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
389 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
390 self.weak_binder.partial_cmp(&other.weak_binder)
391 }
392}
393
394impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
395 fn eq(&self, other: &Self) -> bool {
396 self.weak_binder == other.weak_binder
397 }
398}
399
400impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
401
Stephen Crane2a3c2502020-06-16 17:48:35 -0700402/// Create a function implementing a static getter for an interface class.
403///
404/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
405/// [`Interface`]) must have global, static class that uniquely identifies
406/// it. This macro implements an [`InterfaceClass`] getter to simplify these
407/// implementations.
408///
409/// The type of a structure that implements [`InterfaceClassMethods`] must be
410/// passed to this macro. For local services, this should be `Binder<Self>`
411/// since [`Binder`] implements [`InterfaceClassMethods`].
412///
413/// # Examples
414///
415/// When implementing a local [`Remotable`] service `ExampleService`, the
416/// `get_class` method is required in the [`Remotable`] impl block. This macro
417/// should be used as follows to implement this functionality:
418///
419/// ```rust
420/// impl Remotable for ExampleService {
421/// fn get_descriptor() -> &'static str {
422/// "android.os.IExampleInterface"
423/// }
424///
425/// fn on_transact(
426/// &self,
427/// code: TransactionCode,
428/// data: &Parcel,
429/// reply: &mut Parcel,
430/// ) -> Result<()> {
431/// // ...
432/// }
433///
434/// binder_fn_get_class!(Binder<Self>);
435/// }
436/// ```
437macro_rules! binder_fn_get_class {
438 ($class:ty) => {
439 binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
440 };
441
442 ($constructor:expr) => {
443 fn get_class() -> $crate::InterfaceClass {
444 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
445 static mut CLASS: Option<$crate::InterfaceClass> = None;
446
447 CLASS_INIT.call_once(|| unsafe {
448 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
449 // variable, and therefore is thread-safe, as it can only occur
450 // once.
451 CLASS = Some($constructor);
452 });
453 unsafe {
454 // Safety: The `CLASS` variable can only be mutated once, above,
455 // and is subsequently safe to read from any thread.
456 CLASS.unwrap()
457 }
458 }
459 };
460}
461
462pub trait InterfaceClassMethods {
463 /// Get the interface descriptor string for this object type.
464 fn get_descriptor() -> &'static str
465 where
466 Self: Sized;
467
468 /// Called during construction of a new `AIBinder` object of this interface
469 /// class.
470 ///
471 /// The opaque pointer parameter will be the parameter provided to
472 /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
473 /// `AIBinder` object.
474 ///
475 /// # Safety
476 ///
477 /// Callback called from C++. The parameter argument provided to
478 /// `AIBinder_new` must match the type expected here. The `AIBinder` object
479 /// will take ownership of the returned pointer, which it will free via
480 /// `on_destroy`.
481 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
482
483 /// Called when a transaction needs to be processed by the local service
484 /// implementation.
485 ///
486 /// # Safety
487 ///
488 /// Callback called from C++. The `binder` parameter must be a valid pointer
489 /// to a binder object of this class with userdata initialized via this
490 /// class's `on_create`. The parcel parameters must be valid pointers to
491 /// parcel objects.
492 unsafe extern "C" fn on_transact(
493 binder: *mut sys::AIBinder,
494 code: u32,
495 data: *const sys::AParcel,
496 reply: *mut sys::AParcel,
497 ) -> status_t;
498
499 /// Called whenever an `AIBinder` object is no longer referenced and needs
500 /// to be destroyed.
501 ///
502 /// # Safety
503 ///
504 /// Callback called from C++. The opaque pointer parameter must be the value
505 /// returned by `on_create` for this class. This function takes ownership of
506 /// the provided pointer and destroys it.
507 unsafe extern "C" fn on_destroy(object: *mut c_void);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700508
509 /// Called to handle the `dump` transaction.
510 ///
511 /// # Safety
512 ///
513 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
514 /// contains a `T` pointer in its user data. fd should be a non-owned file
515 /// descriptor, and args must be an array of null-terminated string
516 /// poiinters with length num_args.
517 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 -0700518}
519
520/// Interface for transforming a generic SpIBinder into a specific remote
521/// interface trait.
522///
523/// # Example
524///
525/// For Binder interface `IFoo`, the following implementation should be made:
526/// ```no_run
527/// # use binder::{FromIBinder, SpIBinder, Result};
528/// # trait IFoo {}
529/// impl FromIBinder for dyn IFoo {
530/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
531/// // ...
532/// # Err(binder::StatusCode::OK)
533/// }
534/// }
535/// ```
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800536pub trait FromIBinder: Interface {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700537 /// Try to interpret a generic Binder object as this interface.
538 ///
539 /// Returns a trait object for the `Self` interface if this object
540 /// implements that interface.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800541 fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700542}
543
544/// Trait for transparent Rust wrappers around android C++ native types.
545///
546/// The pointer return by this trait's methods should be immediately passed to
547/// C++ and not stored by Rust. The pointer is valid only as long as the
548/// underlying C++ object is alive, so users must be careful to take this into
549/// account, as Rust cannot enforce this.
550///
551/// # Safety
552///
553/// For this trait to be a correct implementation, `T` must be a valid android
554/// C++ type. Since we cannot constrain this via the type system, this trait is
555/// marked as unsafe.
556pub unsafe trait AsNative<T> {
557 /// Return a pointer to the native version of `self`
558 fn as_native(&self) -> *const T;
559
560 /// Return a mutable pointer to the native version of `self`
561 fn as_native_mut(&mut self) -> *mut T;
562}
563
564unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
565 fn as_native(&self) -> *const T {
566 self.as_ref().map_or(ptr::null(), |v| v.as_native())
567 }
568
569 fn as_native_mut(&mut self) -> *mut T {
570 self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
571 }
572}
573
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000574/// The features to enable when creating a native Binder.
575///
576/// This should always be initialised with a default value, e.g.:
577/// ```
578/// # use binder::BinderFeatures;
579/// BinderFeatures {
580/// set_requesting_sid: true,
581/// ..BinderFeatures::default(),
582/// }
583/// ```
584#[derive(Clone, Debug, Default, Eq, PartialEq)]
585pub struct BinderFeatures {
586 /// Indicates that the service intends to receive caller security contexts. This must be true
587 /// for `ThreadState::with_calling_sid` to work.
588 pub set_requesting_sid: bool,
589 // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
590 // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
591 // expressions entirely.
592 #[doc(hidden)]
593 pub _non_exhaustive: (),
594}
595
Stephen Crane2a3c2502020-06-16 17:48:35 -0700596/// Declare typed interfaces for a binder object.
597///
598/// Given an interface trait and descriptor string, create a native and remote
599/// proxy wrapper for this interface. The native service object (`$native`)
600/// implements `Remotable` and will dispatch to the function `$on_transact` to
601/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
602/// objects for this interface and can optionally contain additional fields.
603///
604/// Assuming the interface trait is `Interface`, `$on_transact` function must
605/// have the following type:
606///
607/// ```
608/// # use binder::{Interface, TransactionCode, Parcel};
609/// # trait Placeholder {
610/// fn on_transact(
611/// service: &dyn Interface,
612/// code: TransactionCode,
613/// data: &Parcel,
614/// reply: &mut Parcel,
615/// ) -> binder::Result<()>;
616/// # }
617/// ```
618///
619/// # Examples
620///
621/// The following example declares the local service type `BnServiceManager` and
622/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
623/// proxy respectively) for the `IServiceManager` Binder interface. The
624/// interfaces will be identified by the descriptor string
625/// "android.os.IServiceManager". The local service will dispatch transactions
626/// using the provided function, `on_transact`.
627///
628/// ```
629/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
630///
631/// pub trait IServiceManager: Interface {
632/// // remote methods...
633/// }
634///
635/// declare_binder_interface! {
636/// IServiceManager["android.os.IServiceManager"] {
637/// native: BnServiceManager(on_transact),
638/// proxy: BpServiceManager,
639/// }
640/// }
641///
642/// fn on_transact(
643/// service: &dyn IServiceManager,
644/// code: TransactionCode,
645/// data: &Parcel,
646/// reply: &mut Parcel,
647/// ) -> binder::Result<()> {
648/// // ...
649/// Ok(())
650/// }
651///
652/// impl IServiceManager for BpServiceManager {
653/// // parceling/unparceling code for the IServiceManager emitted here
654/// }
655///
656/// impl IServiceManager for Binder<BnServiceManager> {
657/// // Forward calls to local implementation
658/// }
659/// ```
660#[macro_export]
661macro_rules! declare_binder_interface {
662 {
663 $interface:path[$descriptor:expr] {
664 native: $native:ident($on_transact:path),
665 proxy: $proxy:ident,
666 }
667 } => {
668 $crate::declare_binder_interface! {
669 $interface[$descriptor] {
670 native: $native($on_transact),
671 proxy: $proxy {},
Stephen Craneff7f03a2021-02-25 16:04:22 -0800672 stability: $crate::Stability::default(),
673 }
674 }
675 };
676
677 {
678 $interface:path[$descriptor:expr] {
679 native: $native:ident($on_transact:path),
680 proxy: $proxy:ident,
681 stability: $stability:expr,
682 }
683 } => {
684 $crate::declare_binder_interface! {
685 $interface[$descriptor] {
686 native: $native($on_transact),
687 proxy: $proxy {},
688 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700689 }
690 }
691 };
692
693 {
694 $interface:path[$descriptor:expr] {
695 native: $native:ident($on_transact:path),
696 proxy: $proxy:ident {
697 $($fname:ident: $fty:ty = $finit:expr),*
698 },
699 }
700 } => {
701 $crate::declare_binder_interface! {
702 $interface[$descriptor] {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800703 native: $native($on_transact),
704 proxy: $proxy {
705 $($fname: $fty = $finit),*
706 },
707 stability: $crate::Stability::default(),
708 }
709 }
710 };
711
712 {
713 $interface:path[$descriptor:expr] {
714 native: $native:ident($on_transact:path),
715 proxy: $proxy:ident {
716 $($fname:ident: $fty:ty = $finit:expr),*
717 },
718 stability: $stability:expr,
719 }
720 } => {
721 $crate::declare_binder_interface! {
722 $interface[$descriptor] {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700723 @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
724 native: $native($on_transact),
725 @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
726 proxy: $proxy {
727 $($fname: $fty = $finit),*
728 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800729 stability: $stability,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700730 }
731 }
732 };
733
734 {
735 $interface:path[$descriptor:expr] {
736 @doc[$native_doc:expr]
737 native: $native:ident($on_transact:path),
738
739 @doc[$proxy_doc:expr]
740 proxy: $proxy:ident {
741 $($fname:ident: $fty:ty = $finit:expr),*
742 },
Stephen Craneff7f03a2021-02-25 16:04:22 -0800743
744 stability: $stability:expr,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700745 }
746 } => {
747 #[doc = $proxy_doc]
748 pub struct $proxy {
749 binder: $crate::SpIBinder,
750 $($fname: $fty,)*
751 }
752
753 impl $crate::Interface for $proxy {
754 fn as_binder(&self) -> $crate::SpIBinder {
755 self.binder.clone()
756 }
757 }
758
759 impl $crate::Proxy for $proxy
760 where
761 $proxy: $interface,
762 {
763 fn get_descriptor() -> &'static str {
764 $descriptor
765 }
766
767 fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
Stephen Crane669deb62020-09-10 17:31:39 -0700768 Ok(Self { binder, $($fname: $finit),* })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700769 }
770 }
771
772 #[doc = $native_doc]
773 #[repr(transparent)]
774 pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
775
776 impl $native {
777 /// Create a new binder service.
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000778 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
779 let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
780 $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800781 $crate::Strong::new(Box::new(binder))
Stephen Crane2a3c2502020-06-16 17:48:35 -0700782 }
783 }
784
785 impl $crate::Remotable for $native {
786 fn get_descriptor() -> &'static str {
787 $descriptor
788 }
789
790 fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
Andrei Homescu32814372020-08-20 15:36:08 -0700791 match $on_transact(&*self.0, code, data, reply) {
792 // The C++ backend converts UNEXPECTED_NULL into an exception
793 Err($crate::StatusCode::UNEXPECTED_NULL) => {
794 let status = $crate::Status::new_exception(
795 $crate::ExceptionCode::NULL_POINTER,
796 None,
797 );
798 reply.write(&status)
799 },
800 result => result
801 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700802 }
803
Stephen Crane2a3297f2021-06-11 16:48:10 -0700804 fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> {
805 self.0.dump(file, args)
806 }
807
Stephen Crane2a3c2502020-06-16 17:48:35 -0700808 fn get_class() -> $crate::InterfaceClass {
809 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
810 static mut CLASS: Option<$crate::InterfaceClass> = None;
811
812 CLASS_INIT.call_once(|| unsafe {
813 // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
814 // variable, and therefore is thread-safe, as it can only occur
815 // once.
816 CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
817 });
818 unsafe {
819 // Safety: The `CLASS` variable can only be mutated once, above,
820 // and is subsequently safe to read from any thread.
821 CLASS.unwrap()
822 }
823 }
824 }
825
826 impl $crate::FromIBinder for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800827 fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700828 use $crate::AssociateClass;
Stephen Crane669deb62020-09-10 17:31:39 -0700829
830 let existing_class = ibinder.get_class();
831 if let Some(class) = existing_class {
832 if class != <$native as $crate::Remotable>::get_class() &&
833 class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
834 {
835 // The binder object's descriptor string matches what we
836 // expect. We still need to treat this local or already
837 // associated object as remote, because we can't cast it
838 // into a Rust service object without a matching class
839 // pointer.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800840 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700841 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700842 }
843
Stephen Crane669deb62020-09-10 17:31:39 -0700844 if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
845 let service: $crate::Result<$crate::Binder<$native>> =
846 std::convert::TryFrom::try_from(ibinder.clone());
847 if let Ok(service) = service {
848 // We were able to associate with our expected class and
849 // the service is local.
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800850 return Ok($crate::Strong::new(Box::new(service)));
Stephen Crane669deb62020-09-10 17:31:39 -0700851 } else {
852 // Service is remote
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800853 return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
Stephen Crane669deb62020-09-10 17:31:39 -0700854 }
Matthew Maurerf6b9ad92020-12-03 19:27:25 +0000855 }
Stephen Crane669deb62020-09-10 17:31:39 -0700856
857 Err($crate::StatusCode::BAD_TYPE.into())
Stephen Crane2a3c2502020-06-16 17:48:35 -0700858 }
859 }
860
861 impl $crate::parcel::Serialize for dyn $interface + '_
862 where
Stephen Craned58bce02020-07-07 12:26:02 -0700863 dyn $interface: $crate::Interface
Stephen Crane2a3c2502020-06-16 17:48:35 -0700864 {
865 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
866 let binder = $crate::Interface::as_binder(self);
867 parcel.write(&binder)
868 }
869 }
870
871 impl $crate::parcel::SerializeOption for dyn $interface + '_ {
872 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
873 parcel.write(&this.map($crate::Interface::as_binder))
874 }
875 }
Andrei Homescu2e3c1472020-08-11 16:35:40 -0700876
877 impl std::fmt::Debug for dyn $interface {
878 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
879 f.pad(stringify!($interface))
880 }
881 }
Andrei Homescu64ebd132020-08-07 22:12:48 -0700882
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800883 /// Convert a &dyn $interface to Strong<dyn $interface>
Andrei Homescu64ebd132020-08-07 22:12:48 -0700884 impl std::borrow::ToOwned for dyn $interface {
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800885 type Owned = $crate::Strong<dyn $interface>;
Andrei Homescu64ebd132020-08-07 22:12:48 -0700886 fn to_owned(&self) -> Self::Owned {
887 self.as_binder().into_interface()
888 .expect(concat!("Error cloning interface ", stringify!($interface)))
889 }
890 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700891 };
892}
Andrei Homescu00eca712020-09-09 18:57:40 -0700893
894/// Declare an AIDL enumeration.
895///
896/// This is mainly used internally by the AIDL compiler.
897#[macro_export]
898macro_rules! declare_binder_enum {
899 {
Andrei Homescu7f38cf92021-06-29 23:55:43 +0000900 $enum:ident : [$backing:ty; $size:expr] {
Andrei Homescu00eca712020-09-09 18:57:40 -0700901 $( $name:ident = $value:expr, )*
902 }
903 } => {
904 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
905 pub struct $enum(pub $backing);
906 impl $enum {
907 $( pub const $name: Self = Self($value); )*
Andrei Homescu7f38cf92021-06-29 23:55:43 +0000908
909 #[inline(always)]
910 pub const fn enum_values() -> [Self; $size] {
911 [$(Self::$name),*]
912 }
Andrei Homescu00eca712020-09-09 18:57:40 -0700913 }
914
915 impl $crate::parcel::Serialize for $enum {
916 fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
917 parcel.write(&self.0)
918 }
919 }
920
921 impl $crate::parcel::SerializeArray for $enum {
922 fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
923 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
924 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
925 }
926 }
927
928 impl $crate::parcel::Deserialize for $enum {
929 fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
930 parcel.read().map(Self)
931 }
932 }
933
934 impl $crate::parcel::DeserializeArray for $enum {
935 fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
936 let v: Option<Vec<$backing>> =
937 <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
938 Ok(v.map(|v| v.into_iter().map(Self).collect()))
939 }
940 }
941 };
942}