| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 1 | /* | 
|  | 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 Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 19 | use crate::error::{status_t, Result, StatusCode}; | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 20 | use crate::parcel::{Parcel, BorrowedParcel}; | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 21 | use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 22 | use crate::sys; | 
|  | 23 |  | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 24 | use std::borrow::Borrow; | 
|  | 25 | use std::cmp::Ordering; | 
| Andrei Homescu | ee132fa | 2021-09-03 02:36:17 +0000 | [diff] [blame] | 26 | use std::convert::TryFrom; | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 27 | use std::ffi::{c_void, CStr, CString}; | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 28 | use std::fmt; | 
| Stephen Crane | 2a3297f | 2021-06-11 16:48:10 -0700 | [diff] [blame] | 29 | use std::fs::File; | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 30 | use std::marker::PhantomData; | 
|  | 31 | use std::ops::Deref; | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 32 | use std::os::raw::c_char; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 33 | use std::os::unix::io::AsRawFd; | 
|  | 34 | use std::ptr; | 
|  | 35 |  | 
|  | 36 | /// Binder action to perform. | 
|  | 37 | /// | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 38 | /// This must be a number between [`FIRST_CALL_TRANSACTION`] and | 
|  | 39 | /// [`LAST_CALL_TRANSACTION`]. | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 40 | pub type TransactionCode = u32; | 
|  | 41 |  | 
|  | 42 | /// Additional operation flags. | 
|  | 43 | /// | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 44 | /// `FLAG_*` values. | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 45 | pub type TransactionFlags = u32; | 
|  | 46 |  | 
|  | 47 | /// Super-trait for Binder interfaces. | 
|  | 48 | /// | 
|  | 49 | /// This trait allows conversion of a Binder interface trait object into an | 
|  | 50 | /// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL | 
|  | 51 | /// interfaces) must implement this trait. | 
|  | 52 | /// | 
|  | 53 | /// This is equivalent `IInterface` in C++. | 
| Stephen Crane | f03fe3d | 2021-06-25 15:05:00 -0700 | [diff] [blame] | 54 | pub trait Interface: Send + Sync { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 55 | /// Convert this binder object into a generic [`SpIBinder`] reference. | 
|  | 56 | fn as_binder(&self) -> SpIBinder { | 
|  | 57 | panic!("This object was not a Binder object and cannot be converted into an SpIBinder.") | 
|  | 58 | } | 
| Stephen Crane | 2a3297f | 2021-06-11 16:48:10 -0700 | [diff] [blame] | 59 |  | 
|  | 60 | /// Dump transaction handler for this Binder object. | 
|  | 61 | /// | 
|  | 62 | /// This handler is a no-op by default and should be implemented for each | 
|  | 63 | /// Binder service struct that wishes to respond to dump transactions. | 
|  | 64 | fn dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> { | 
|  | 65 | Ok(()) | 
|  | 66 | } | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 67 | } | 
|  | 68 |  | 
| Alice Ryhl | c173684 | 2021-11-23 12:38:51 +0000 | [diff] [blame] | 69 | /// Implemented by sync interfaces to specify what the associated async interface is. | 
|  | 70 | /// Generic to handle the fact that async interfaces are generic over a thread pool. | 
|  | 71 | /// | 
|  | 72 | /// The binder in any object implementing this trait should be compatible with the | 
|  | 73 | /// `Target` associated type, and using `FromIBinder` to convert it to the target | 
|  | 74 | /// should not fail. | 
|  | 75 | pub trait ToAsyncInterface<P> | 
|  | 76 | where | 
|  | 77 | Self: Interface, | 
|  | 78 | Self::Target: FromIBinder, | 
|  | 79 | { | 
|  | 80 | /// The async interface associated with this sync interface. | 
|  | 81 | type Target: ?Sized; | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | /// Implemented by async interfaces to specify what the associated sync interface is. | 
|  | 85 | /// | 
|  | 86 | /// The binder in any object implementing this trait should be compatible with the | 
|  | 87 | /// `Target` associated type, and using `FromIBinder` to convert it to the target | 
|  | 88 | /// should not fail. | 
|  | 89 | pub trait ToSyncInterface | 
|  | 90 | where | 
|  | 91 | Self: Interface, | 
|  | 92 | Self::Target: FromIBinder, | 
|  | 93 | { | 
|  | 94 | /// The sync interface associated with this async interface. | 
|  | 95 | type Target: ?Sized; | 
|  | 96 | } | 
|  | 97 |  | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 98 | /// Interface stability promise | 
|  | 99 | /// | 
|  | 100 | /// An interface can promise to be a stable vendor interface ([`Vintf`]), or | 
|  | 101 | /// makes no stability guarantees ([`Local`]). [`Local`] is | 
|  | 102 | /// currently the default stability. | 
| Andrei Homescu | ee132fa | 2021-09-03 02:36:17 +0000 | [diff] [blame] | 103 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 104 | pub enum Stability { | 
|  | 105 | /// Default stability, visible to other modules in the same compilation | 
|  | 106 | /// context (e.g. modules on system.img) | 
|  | 107 | Local, | 
|  | 108 |  | 
|  | 109 | /// A Vendor Interface Object, which promises to be stable | 
|  | 110 | Vintf, | 
|  | 111 | } | 
|  | 112 |  | 
|  | 113 | impl Default for Stability { | 
|  | 114 | fn default() -> Self { | 
|  | 115 | Stability::Local | 
|  | 116 | } | 
|  | 117 | } | 
|  | 118 |  | 
| Andrei Homescu | ee132fa | 2021-09-03 02:36:17 +0000 | [diff] [blame] | 119 | impl From<Stability> for i32 { | 
|  | 120 | fn from(stability: Stability) -> i32 { | 
|  | 121 | use Stability::*; | 
|  | 122 | match stability { | 
|  | 123 | Local => 0, | 
|  | 124 | Vintf => 1, | 
|  | 125 | } | 
|  | 126 | } | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | impl TryFrom<i32> for Stability { | 
|  | 130 | type Error = StatusCode; | 
|  | 131 | fn try_from(stability: i32) -> Result<Stability> { | 
|  | 132 | use Stability::*; | 
|  | 133 | match stability { | 
|  | 134 | 0 => Ok(Local), | 
|  | 135 | 1 => Ok(Vintf), | 
|  | 136 | _ => Err(StatusCode::BAD_VALUE) | 
|  | 137 | } | 
|  | 138 | } | 
|  | 139 | } | 
|  | 140 |  | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 141 | /// A local service that can be remotable via Binder. | 
|  | 142 | /// | 
|  | 143 | /// An object that implement this interface made be made into a Binder service | 
|  | 144 | /// via `Binder::new(object)`. | 
|  | 145 | /// | 
|  | 146 | /// This is a low-level interface that should normally be automatically | 
|  | 147 | /// generated from AIDL via the [`declare_binder_interface!`] macro. When using | 
|  | 148 | /// the AIDL backend, users need only implement the high-level AIDL-defined | 
|  | 149 | /// interface. The AIDL compiler then generates a container struct that wraps | 
|  | 150 | /// the user-defined service and implements `Remotable`. | 
| Andrei Homescu | 2c674b0 | 2020-08-07 22:12:27 -0700 | [diff] [blame] | 151 | pub trait Remotable: Send + Sync { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 152 | /// The Binder interface descriptor string. | 
|  | 153 | /// | 
|  | 154 | /// This string is a unique identifier for a Binder interface, and should be | 
|  | 155 | /// the same between all implementations of that interface. | 
|  | 156 | fn get_descriptor() -> &'static str; | 
|  | 157 |  | 
|  | 158 | /// Handle and reply to a request to invoke a transaction on this object. | 
|  | 159 | /// | 
|  | 160 | /// `reply` may be [`None`] if the sender does not expect a reply. | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 161 | fn on_transact(&self, code: TransactionCode, data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>) -> Result<()>; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 162 |  | 
| Stephen Crane | 2a3297f | 2021-06-11 16:48:10 -0700 | [diff] [blame] | 163 | /// Handle a request to invoke the dump transaction on this | 
|  | 164 | /// object. | 
|  | 165 | fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>; | 
|  | 166 |  | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 167 | /// Retrieve the class of this remote object. | 
|  | 168 | /// | 
|  | 169 | /// This method should always return the same InterfaceClass for the same | 
|  | 170 | /// type. | 
|  | 171 | fn get_class() -> InterfaceClass; | 
|  | 172 | } | 
|  | 173 |  | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 174 | /// First transaction code available for user commands (inclusive) | 
|  | 175 | pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION; | 
|  | 176 | /// Last transaction code available for user commands (inclusive) | 
|  | 177 | pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION; | 
|  | 178 |  | 
|  | 179 | /// Corresponds to TF_ONE_WAY -- an asynchronous call. | 
|  | 180 | pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY; | 
|  | 181 | /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made. | 
|  | 182 | pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF; | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 183 | /// Set to the vendor flag if we are building for the VNDK, 0 otherwise | 
|  | 184 | pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL; | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 185 |  | 
|  | 186 | /// Internal interface of binder local or remote objects for making | 
|  | 187 | /// transactions. | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 188 | /// | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 189 | /// This trait corresponds to the parts of the interface of the C++ `IBinder` | 
|  | 190 | /// class which are internal implementation details. | 
|  | 191 | pub trait IBinderInternal: IBinder { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 192 | /// Is this object still alive? | 
|  | 193 | fn is_binder_alive(&self) -> bool; | 
|  | 194 |  | 
|  | 195 | /// Send a ping transaction to this object | 
|  | 196 | fn ping_binder(&mut self) -> Result<()>; | 
|  | 197 |  | 
| Janis Danisevskis | 798a09a | 2020-08-18 08:35:38 -0700 | [diff] [blame] | 198 | /// Indicate that the service intends to receive caller security contexts. | 
| Janis Danisevskis | 1323d51 | 2021-11-09 07:48:08 -0800 | [diff] [blame] | 199 | #[cfg(not(android_vndk))] | 
| Janis Danisevskis | 798a09a | 2020-08-18 08:35:38 -0700 | [diff] [blame] | 200 | fn set_requesting_sid(&mut self, enable: bool); | 
|  | 201 |  | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 202 | /// 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 Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 209 | /// Create a Parcel that can be used with `submit_transact`. | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 210 | fn prepare_transact(&self) -> Result<Parcel>; | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 211 |  | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 212 | /// Perform a generic operation with the object. | 
|  | 213 | /// | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 214 | /// The provided [`Parcel`] must have been created by a call to | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 215 | /// `prepare_transact` on the same binder. | 
|  | 216 | /// | 
|  | 217 | /// # Arguments | 
|  | 218 | /// | 
|  | 219 | /// * `code` - Transaction code for the operation. | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 220 | /// * `data` - [`Parcel`] with input data. | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 221 | /// * `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 Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 226 | data: Parcel, | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 227 | flags: TransactionFlags, | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 228 | ) -> Result<Parcel>; | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 229 |  | 
|  | 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 Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 234 | /// # Arguments | 
|  | 235 | /// * `code` - Transaction code for the operation | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 236 | /// * `flags` - Transaction flags, e.g. marking the transaction as | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 237 | ///   asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)) | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 238 | /// * `input_callback` A callback for building the `Parcel`. | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 239 | fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>( | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 240 | &self, | 
|  | 241 | code: TransactionCode, | 
|  | 242 | flags: TransactionFlags, | 
|  | 243 | input_callback: F, | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 244 | ) -> Result<Parcel> { | 
|  | 245 | let mut parcel = self.prepare_transact()?; | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 246 | input_callback(parcel.borrowed())?; | 
|  | 247 | self.submit_transact(code, parcel, flags) | 
| Alice Ryhl | feba6ca | 2021-08-19 10:47:04 +0000 | [diff] [blame] | 248 | } | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 249 | } | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 250 |  | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 251 | /// 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. | 
|  | 255 | pub trait IBinder { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 256 | /// 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 Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 259 | /// then the `DeathRecipient`'s callback will be called. | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 260 | /// | 
|  | 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 | /// | 
|  | 266 | /// This link always holds a weak reference to its recipient. | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 267 | fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; | 
|  | 268 |  | 
|  | 269 | /// Remove a previously registered death notification. | 
|  | 270 | /// The recipient will no longer be called if this object | 
|  | 271 | /// dies. | 
|  | 272 | fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; | 
|  | 273 | } | 
|  | 274 |  | 
|  | 275 | /// Opaque reference to the type of a Binder interface. | 
|  | 276 | /// | 
|  | 277 | /// This object encapsulates the Binder interface descriptor string, along with | 
|  | 278 | /// the binder transaction callback, if the class describes a local service. | 
|  | 279 | /// | 
|  | 280 | /// A Binder remotable object may only have a single interface class, and any | 
|  | 281 | /// given object can only be associated with one class. Two objects with | 
|  | 282 | /// different classes are incompatible, even if both classes have the same | 
|  | 283 | /// interface descriptor. | 
|  | 284 | #[derive(Copy, Clone, PartialEq, Eq)] | 
|  | 285 | pub struct InterfaceClass(*const sys::AIBinder_Class); | 
|  | 286 |  | 
|  | 287 | impl InterfaceClass { | 
|  | 288 | /// Get a Binder NDK `AIBinder_Class` pointer for this object type. | 
|  | 289 | /// | 
|  | 290 | /// Note: the returned pointer will not be constant. Calling this method | 
|  | 291 | /// multiple times for the same type will result in distinct class | 
|  | 292 | /// pointers. A static getter for this value is implemented in | 
|  | 293 | /// [`declare_binder_interface!`]. | 
|  | 294 | pub fn new<I: InterfaceClassMethods>() -> InterfaceClass { | 
|  | 295 | let descriptor = CString::new(I::get_descriptor()).unwrap(); | 
|  | 296 | let ptr = unsafe { | 
|  | 297 | // Safety: `AIBinder_Class_define` expects a valid C string, and | 
|  | 298 | // three valid callback functions, all non-null pointers. The C | 
|  | 299 | // string is copied and need not be valid for longer than the call, | 
|  | 300 | // so we can drop it after the call. We can safely assign null to | 
|  | 301 | // the onDump and handleShellCommand callbacks as long as the class | 
|  | 302 | // pointer was non-null. Rust None for a Option<fn> is guaranteed to | 
|  | 303 | // be a NULL pointer. Rust retains ownership of the pointer after it | 
|  | 304 | // is defined. | 
|  | 305 | let class = sys::AIBinder_Class_define( | 
|  | 306 | descriptor.as_ptr(), | 
|  | 307 | Some(I::on_create), | 
|  | 308 | Some(I::on_destroy), | 
|  | 309 | Some(I::on_transact), | 
|  | 310 | ); | 
|  | 311 | if class.is_null() { | 
|  | 312 | panic!("Expected non-null class pointer from AIBinder_Class_define!"); | 
|  | 313 | } | 
| Stephen Crane | 2a3297f | 2021-06-11 16:48:10 -0700 | [diff] [blame] | 314 | sys::AIBinder_Class_setOnDump(class, Some(I::on_dump)); | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 315 | sys::AIBinder_Class_setHandleShellCommand(class, None); | 
|  | 316 | class | 
|  | 317 | }; | 
|  | 318 | InterfaceClass(ptr) | 
|  | 319 | } | 
|  | 320 |  | 
|  | 321 | /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class` | 
|  | 322 | /// pointer. | 
|  | 323 | /// | 
|  | 324 | /// # Safety | 
|  | 325 | /// | 
|  | 326 | /// This function is safe iff `ptr` is a valid, non-null pointer to an | 
|  | 327 | /// `AIBinder_Class`. | 
|  | 328 | pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass { | 
|  | 329 | InterfaceClass(ptr) | 
|  | 330 | } | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 331 |  | 
|  | 332 | /// Get the interface descriptor string of this class. | 
|  | 333 | pub fn get_descriptor(&self) -> String { | 
|  | 334 | unsafe { | 
|  | 335 | // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor | 
|  | 336 | // is always a two-byte null terminated sequence of u16s. Thus, we | 
|  | 337 | // can continue reading from the pointer until we hit a null value, | 
|  | 338 | // and this pointer can be a valid slice if the slice length is <= | 
|  | 339 | // the number of u16 elements before the null terminator. | 
|  | 340 |  | 
|  | 341 | let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0); | 
| Andrew Walbran | 12400d8 | 2021-03-04 17:04:34 +0000 | [diff] [blame] | 342 | CStr::from_ptr(raw_descriptor) | 
|  | 343 | .to_str() | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 344 | .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor") | 
|  | 345 | .into() | 
|  | 346 | } | 
|  | 347 | } | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 348 | } | 
|  | 349 |  | 
|  | 350 | impl From<InterfaceClass> for *const sys::AIBinder_Class { | 
|  | 351 | fn from(class: InterfaceClass) -> *const sys::AIBinder_Class { | 
|  | 352 | class.0 | 
|  | 353 | } | 
|  | 354 | } | 
|  | 355 |  | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 356 | /// Strong reference to a binder object | 
|  | 357 | pub struct Strong<I: FromIBinder + ?Sized>(Box<I>); | 
|  | 358 |  | 
|  | 359 | impl<I: FromIBinder + ?Sized> Strong<I> { | 
|  | 360 | /// Create a new strong reference to the provided binder object | 
|  | 361 | pub fn new(binder: Box<I>) -> Self { | 
|  | 362 | Self(binder) | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | /// Construct a new weak reference to this binder | 
|  | 366 | pub fn downgrade(this: &Strong<I>) -> Weak<I> { | 
|  | 367 | Weak::new(this) | 
|  | 368 | } | 
| Alice Ryhl | c173684 | 2021-11-23 12:38:51 +0000 | [diff] [blame] | 369 |  | 
|  | 370 | /// Convert this synchronous binder handle into an asynchronous one. | 
|  | 371 | pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target> | 
|  | 372 | where | 
|  | 373 | I: ToAsyncInterface<P>, | 
|  | 374 | { | 
|  | 375 | // By implementing the ToAsyncInterface trait, it is guaranteed that the binder | 
|  | 376 | // object is also valid for the target type. | 
|  | 377 | FromIBinder::try_from(self.0.as_binder()).unwrap() | 
|  | 378 | } | 
|  | 379 |  | 
|  | 380 | /// Convert this asynchronous binder handle into a synchronous one. | 
|  | 381 | pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target> | 
|  | 382 | where | 
|  | 383 | I: ToSyncInterface, | 
|  | 384 | { | 
|  | 385 | // By implementing the ToSyncInterface trait, it is guaranteed that the binder | 
|  | 386 | // object is also valid for the target type. | 
|  | 387 | FromIBinder::try_from(self.0.as_binder()).unwrap() | 
|  | 388 | } | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 389 | } | 
|  | 390 |  | 
|  | 391 | impl<I: FromIBinder + ?Sized> Clone for Strong<I> { | 
|  | 392 | fn clone(&self) -> Self { | 
|  | 393 | // Since we hold a strong reference, we should always be able to create | 
|  | 394 | // a new strong reference to the same interface type, so try_from() | 
|  | 395 | // should never fail here. | 
|  | 396 | FromIBinder::try_from(self.0.as_binder()).unwrap() | 
|  | 397 | } | 
|  | 398 | } | 
|  | 399 |  | 
|  | 400 | impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> { | 
|  | 401 | fn borrow(&self) -> &I { | 
|  | 402 | &self.0 | 
|  | 403 | } | 
|  | 404 | } | 
|  | 405 |  | 
|  | 406 | impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> { | 
|  | 407 | fn as_ref(&self) -> &I { | 
|  | 408 | &self.0 | 
|  | 409 | } | 
|  | 410 | } | 
|  | 411 |  | 
|  | 412 | impl<I: FromIBinder + ?Sized> Deref for Strong<I> { | 
|  | 413 | type Target = I; | 
|  | 414 |  | 
|  | 415 | fn deref(&self) -> &Self::Target { | 
|  | 416 | &self.0 | 
|  | 417 | } | 
|  | 418 | } | 
|  | 419 |  | 
|  | 420 | impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> { | 
|  | 421 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 
|  | 422 | fmt::Debug::fmt(&**self, f) | 
|  | 423 | } | 
|  | 424 | } | 
|  | 425 |  | 
|  | 426 | impl<I: FromIBinder + ?Sized> Ord for Strong<I> { | 
|  | 427 | fn cmp(&self, other: &Self) -> Ordering { | 
|  | 428 | self.0.as_binder().cmp(&other.0.as_binder()) | 
|  | 429 | } | 
|  | 430 | } | 
|  | 431 |  | 
|  | 432 | impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> { | 
|  | 433 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | 
|  | 434 | self.0.as_binder().partial_cmp(&other.0.as_binder()) | 
|  | 435 | } | 
|  | 436 | } | 
|  | 437 |  | 
|  | 438 | impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> { | 
|  | 439 | fn eq(&self, other: &Self) -> bool { | 
|  | 440 | self.0.as_binder().eq(&other.0.as_binder()) | 
|  | 441 | } | 
|  | 442 | } | 
|  | 443 |  | 
|  | 444 | impl<I: FromIBinder + ?Sized> Eq for Strong<I> {} | 
|  | 445 |  | 
|  | 446 | /// Weak reference to a binder object | 
|  | 447 | #[derive(Debug)] | 
|  | 448 | pub struct Weak<I: FromIBinder + ?Sized> { | 
|  | 449 | weak_binder: WpIBinder, | 
|  | 450 | interface_type: PhantomData<I>, | 
|  | 451 | } | 
|  | 452 |  | 
|  | 453 | impl<I: FromIBinder + ?Sized> Weak<I> { | 
|  | 454 | /// Construct a new weak reference from a strong reference | 
|  | 455 | fn new(binder: &Strong<I>) -> Self { | 
|  | 456 | let weak_binder = binder.as_binder().downgrade(); | 
|  | 457 | Weak { | 
|  | 458 | weak_binder, | 
|  | 459 | interface_type: PhantomData, | 
|  | 460 | } | 
|  | 461 | } | 
|  | 462 |  | 
|  | 463 | /// Upgrade this weak reference to a strong reference if the binder object | 
|  | 464 | /// is still alive | 
|  | 465 | pub fn upgrade(&self) -> Result<Strong<I>> { | 
|  | 466 | self.weak_binder | 
|  | 467 | .promote() | 
|  | 468 | .ok_or(StatusCode::DEAD_OBJECT) | 
|  | 469 | .and_then(FromIBinder::try_from) | 
|  | 470 | } | 
|  | 471 | } | 
|  | 472 |  | 
|  | 473 | impl<I: FromIBinder + ?Sized> Clone for Weak<I> { | 
|  | 474 | fn clone(&self) -> Self { | 
|  | 475 | Self { | 
|  | 476 | weak_binder: self.weak_binder.clone(), | 
|  | 477 | interface_type: PhantomData, | 
|  | 478 | } | 
|  | 479 | } | 
|  | 480 | } | 
|  | 481 |  | 
|  | 482 | impl<I: FromIBinder + ?Sized> Ord for Weak<I> { | 
|  | 483 | fn cmp(&self, other: &Self) -> Ordering { | 
|  | 484 | self.weak_binder.cmp(&other.weak_binder) | 
|  | 485 | } | 
|  | 486 | } | 
|  | 487 |  | 
|  | 488 | impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> { | 
|  | 489 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | 
|  | 490 | self.weak_binder.partial_cmp(&other.weak_binder) | 
|  | 491 | } | 
|  | 492 | } | 
|  | 493 |  | 
|  | 494 | impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> { | 
|  | 495 | fn eq(&self, other: &Self) -> bool { | 
|  | 496 | self.weak_binder == other.weak_binder | 
|  | 497 | } | 
|  | 498 | } | 
|  | 499 |  | 
|  | 500 | impl<I: FromIBinder + ?Sized> Eq for Weak<I> {} | 
|  | 501 |  | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 502 | /// Create a function implementing a static getter for an interface class. | 
|  | 503 | /// | 
|  | 504 | /// Each binder interface (i.e. local [`Remotable`] service or remote proxy | 
|  | 505 | /// [`Interface`]) must have global, static class that uniquely identifies | 
|  | 506 | /// it. This macro implements an [`InterfaceClass`] getter to simplify these | 
|  | 507 | /// implementations. | 
|  | 508 | /// | 
|  | 509 | /// The type of a structure that implements [`InterfaceClassMethods`] must be | 
|  | 510 | /// passed to this macro. For local services, this should be `Binder<Self>` | 
|  | 511 | /// since [`Binder`] implements [`InterfaceClassMethods`]. | 
|  | 512 | /// | 
|  | 513 | /// # Examples | 
|  | 514 | /// | 
|  | 515 | /// When implementing a local [`Remotable`] service `ExampleService`, the | 
|  | 516 | /// `get_class` method is required in the [`Remotable`] impl block. This macro | 
|  | 517 | /// should be used as follows to implement this functionality: | 
|  | 518 | /// | 
|  | 519 | /// ```rust | 
|  | 520 | /// impl Remotable for ExampleService { | 
|  | 521 | ///     fn get_descriptor() -> &'static str { | 
|  | 522 | ///         "android.os.IExampleInterface" | 
|  | 523 | ///     } | 
|  | 524 | /// | 
|  | 525 | ///     fn on_transact( | 
|  | 526 | ///         &self, | 
|  | 527 | ///         code: TransactionCode, | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 528 | ///         data: &BorrowedParcel, | 
|  | 529 | ///         reply: &mut BorrowedParcel, | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 530 | ///     ) -> Result<()> { | 
|  | 531 | ///         // ... | 
|  | 532 | ///     } | 
|  | 533 | /// | 
|  | 534 | ///     binder_fn_get_class!(Binder<Self>); | 
|  | 535 | /// } | 
|  | 536 | /// ``` | 
|  | 537 | macro_rules! binder_fn_get_class { | 
|  | 538 | ($class:ty) => { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 539 | binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>()); | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 540 | }; | 
|  | 541 |  | 
|  | 542 | ($constructor:expr) => { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 543 | fn get_class() -> $crate::binder_impl::InterfaceClass { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 544 | static CLASS_INIT: std::sync::Once = std::sync::Once::new(); | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 545 | static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 546 |  | 
|  | 547 | CLASS_INIT.call_once(|| unsafe { | 
|  | 548 | // Safety: This assignment is guarded by the `CLASS_INIT` `Once` | 
|  | 549 | // variable, and therefore is thread-safe, as it can only occur | 
|  | 550 | // once. | 
|  | 551 | CLASS = Some($constructor); | 
|  | 552 | }); | 
|  | 553 | unsafe { | 
|  | 554 | // Safety: The `CLASS` variable can only be mutated once, above, | 
|  | 555 | // and is subsequently safe to read from any thread. | 
|  | 556 | CLASS.unwrap() | 
|  | 557 | } | 
|  | 558 | } | 
|  | 559 | }; | 
|  | 560 | } | 
|  | 561 |  | 
|  | 562 | pub trait InterfaceClassMethods { | 
|  | 563 | /// Get the interface descriptor string for this object type. | 
|  | 564 | fn get_descriptor() -> &'static str | 
|  | 565 | where | 
|  | 566 | Self: Sized; | 
|  | 567 |  | 
|  | 568 | /// Called during construction of a new `AIBinder` object of this interface | 
|  | 569 | /// class. | 
|  | 570 | /// | 
|  | 571 | /// The opaque pointer parameter will be the parameter provided to | 
|  | 572 | /// `AIBinder_new`. Returns an opaque userdata to be associated with the new | 
|  | 573 | /// `AIBinder` object. | 
|  | 574 | /// | 
|  | 575 | /// # Safety | 
|  | 576 | /// | 
|  | 577 | /// Callback called from C++. The parameter argument provided to | 
|  | 578 | /// `AIBinder_new` must match the type expected here. The `AIBinder` object | 
|  | 579 | /// will take ownership of the returned pointer, which it will free via | 
|  | 580 | /// `on_destroy`. | 
|  | 581 | unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void; | 
|  | 582 |  | 
|  | 583 | /// Called when a transaction needs to be processed by the local service | 
|  | 584 | /// implementation. | 
|  | 585 | /// | 
|  | 586 | /// # Safety | 
|  | 587 | /// | 
|  | 588 | /// Callback called from C++. The `binder` parameter must be a valid pointer | 
|  | 589 | /// to a binder object of this class with userdata initialized via this | 
|  | 590 | /// class's `on_create`. The parcel parameters must be valid pointers to | 
|  | 591 | /// parcel objects. | 
|  | 592 | unsafe extern "C" fn on_transact( | 
|  | 593 | binder: *mut sys::AIBinder, | 
|  | 594 | code: u32, | 
|  | 595 | data: *const sys::AParcel, | 
|  | 596 | reply: *mut sys::AParcel, | 
|  | 597 | ) -> status_t; | 
|  | 598 |  | 
|  | 599 | /// Called whenever an `AIBinder` object is no longer referenced and needs | 
|  | 600 | /// to be destroyed. | 
|  | 601 | /// | 
|  | 602 | /// # Safety | 
|  | 603 | /// | 
|  | 604 | /// Callback called from C++. The opaque pointer parameter must be the value | 
|  | 605 | /// returned by `on_create` for this class. This function takes ownership of | 
|  | 606 | /// the provided pointer and destroys it. | 
|  | 607 | unsafe extern "C" fn on_destroy(object: *mut c_void); | 
| Stephen Crane | 2a3297f | 2021-06-11 16:48:10 -0700 | [diff] [blame] | 608 |  | 
|  | 609 | /// Called to handle the `dump` transaction. | 
|  | 610 | /// | 
|  | 611 | /// # Safety | 
|  | 612 | /// | 
|  | 613 | /// Must be called with a non-null, valid pointer to a local `AIBinder` that | 
|  | 614 | /// contains a `T` pointer in its user data. fd should be a non-owned file | 
|  | 615 | /// descriptor, and args must be an array of null-terminated string | 
|  | 616 | /// poiinters with length num_args. | 
|  | 617 | unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 618 | } | 
|  | 619 |  | 
|  | 620 | /// Interface for transforming a generic SpIBinder into a specific remote | 
|  | 621 | /// interface trait. | 
|  | 622 | /// | 
|  | 623 | /// # Example | 
|  | 624 | /// | 
|  | 625 | /// For Binder interface `IFoo`, the following implementation should be made: | 
|  | 626 | /// ```no_run | 
|  | 627 | /// # use binder::{FromIBinder, SpIBinder, Result}; | 
|  | 628 | /// # trait IFoo {} | 
|  | 629 | /// impl FromIBinder for dyn IFoo { | 
|  | 630 | ///     fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> { | 
|  | 631 | ///         // ... | 
|  | 632 | ///         # Err(binder::StatusCode::OK) | 
|  | 633 | ///     } | 
|  | 634 | /// } | 
|  | 635 | /// ``` | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 636 | pub trait FromIBinder: Interface { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 637 | /// Try to interpret a generic Binder object as this interface. | 
|  | 638 | /// | 
|  | 639 | /// Returns a trait object for the `Self` interface if this object | 
|  | 640 | /// implements that interface. | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 641 | fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 642 | } | 
|  | 643 |  | 
|  | 644 | /// Trait for transparent Rust wrappers around android C++ native types. | 
|  | 645 | /// | 
|  | 646 | /// The pointer return by this trait's methods should be immediately passed to | 
|  | 647 | /// C++ and not stored by Rust. The pointer is valid only as long as the | 
|  | 648 | /// underlying C++ object is alive, so users must be careful to take this into | 
|  | 649 | /// account, as Rust cannot enforce this. | 
|  | 650 | /// | 
|  | 651 | /// # Safety | 
|  | 652 | /// | 
|  | 653 | /// For this trait to be a correct implementation, `T` must be a valid android | 
|  | 654 | /// C++ type. Since we cannot constrain this via the type system, this trait is | 
|  | 655 | /// marked as unsafe. | 
|  | 656 | pub unsafe trait AsNative<T> { | 
|  | 657 | /// Return a pointer to the native version of `self` | 
|  | 658 | fn as_native(&self) -> *const T; | 
|  | 659 |  | 
|  | 660 | /// Return a mutable pointer to the native version of `self` | 
|  | 661 | fn as_native_mut(&mut self) -> *mut T; | 
|  | 662 | } | 
|  | 663 |  | 
|  | 664 | unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> { | 
|  | 665 | fn as_native(&self) -> *const T { | 
|  | 666 | self.as_ref().map_or(ptr::null(), |v| v.as_native()) | 
|  | 667 | } | 
|  | 668 |  | 
|  | 669 | fn as_native_mut(&mut self) -> *mut T { | 
|  | 670 | self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut()) | 
|  | 671 | } | 
|  | 672 | } | 
|  | 673 |  | 
| Andrew Walbran | 88eca4f | 2021-04-13 14:26:01 +0000 | [diff] [blame] | 674 | /// The features to enable when creating a native Binder. | 
|  | 675 | /// | 
|  | 676 | /// This should always be initialised with a default value, e.g.: | 
|  | 677 | /// ``` | 
|  | 678 | /// # use binder::BinderFeatures; | 
|  | 679 | /// BinderFeatures { | 
|  | 680 | ///   set_requesting_sid: true, | 
|  | 681 | ///   ..BinderFeatures::default(), | 
|  | 682 | /// } | 
|  | 683 | /// ``` | 
|  | 684 | #[derive(Clone, Debug, Default, Eq, PartialEq)] | 
|  | 685 | pub struct BinderFeatures { | 
|  | 686 | /// Indicates that the service intends to receive caller security contexts. This must be true | 
|  | 687 | /// for `ThreadState::with_calling_sid` to work. | 
| Janis Danisevskis | 1323d51 | 2021-11-09 07:48:08 -0800 | [diff] [blame] | 688 | #[cfg(not(android_vndk))] | 
| Andrew Walbran | 88eca4f | 2021-04-13 14:26:01 +0000 | [diff] [blame] | 689 | pub set_requesting_sid: bool, | 
|  | 690 | // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility | 
|  | 691 | // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct | 
|  | 692 | // expressions entirely. | 
|  | 693 | #[doc(hidden)] | 
|  | 694 | pub _non_exhaustive: (), | 
|  | 695 | } | 
|  | 696 |  | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 697 | /// Declare typed interfaces for a binder object. | 
|  | 698 | /// | 
|  | 699 | /// Given an interface trait and descriptor string, create a native and remote | 
|  | 700 | /// proxy wrapper for this interface. The native service object (`$native`) | 
|  | 701 | /// implements `Remotable` and will dispatch to the function `$on_transact` to | 
|  | 702 | /// handle transactions. The typed proxy object (`$proxy`) wraps remote binder | 
|  | 703 | /// objects for this interface and can optionally contain additional fields. | 
|  | 704 | /// | 
|  | 705 | /// Assuming the interface trait is `Interface`, `$on_transact` function must | 
|  | 706 | /// have the following type: | 
|  | 707 | /// | 
|  | 708 | /// ``` | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 709 | /// # use binder::{Interface, TransactionCode, BorrowedParcel}; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 710 | /// # trait Placeholder { | 
|  | 711 | /// fn on_transact( | 
|  | 712 | ///     service: &dyn Interface, | 
|  | 713 | ///     code: TransactionCode, | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 714 | ///     data: &BorrowedParcel, | 
|  | 715 | ///     reply: &mut BorrowedParcel, | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 716 | /// ) -> binder::Result<()>; | 
|  | 717 | /// # } | 
|  | 718 | /// ``` | 
|  | 719 | /// | 
|  | 720 | /// # Examples | 
|  | 721 | /// | 
|  | 722 | /// The following example declares the local service type `BnServiceManager` and | 
|  | 723 | /// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and | 
|  | 724 | /// proxy respectively) for the `IServiceManager` Binder interface. The | 
|  | 725 | /// interfaces will be identified by the descriptor string | 
|  | 726 | /// "android.os.IServiceManager". The local service will dispatch transactions | 
|  | 727 | /// using the provided function, `on_transact`. | 
|  | 728 | /// | 
|  | 729 | /// ``` | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 730 | /// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel}; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 731 | /// | 
|  | 732 | /// pub trait IServiceManager: Interface { | 
|  | 733 | ///     // remote methods... | 
|  | 734 | /// } | 
|  | 735 | /// | 
|  | 736 | /// declare_binder_interface! { | 
|  | 737 | ///     IServiceManager["android.os.IServiceManager"] { | 
|  | 738 | ///         native: BnServiceManager(on_transact), | 
|  | 739 | ///         proxy: BpServiceManager, | 
|  | 740 | ///     } | 
|  | 741 | /// } | 
|  | 742 | /// | 
|  | 743 | /// fn on_transact( | 
|  | 744 | ///     service: &dyn IServiceManager, | 
|  | 745 | ///     code: TransactionCode, | 
| Alice Ryhl | 8618c48 | 2021-11-09 15:35:35 +0000 | [diff] [blame] | 746 | ///     data: &BorrowedParcel, | 
|  | 747 | ///     reply: &mut BorrowedParcel, | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 748 | /// ) -> binder::Result<()> { | 
|  | 749 | ///     // ... | 
|  | 750 | ///     Ok(()) | 
|  | 751 | /// } | 
|  | 752 | /// | 
|  | 753 | /// impl IServiceManager for BpServiceManager { | 
|  | 754 | ///     // parceling/unparceling code for the IServiceManager emitted here | 
|  | 755 | /// } | 
|  | 756 | /// | 
|  | 757 | /// impl IServiceManager for Binder<BnServiceManager> { | 
|  | 758 | ///     // Forward calls to local implementation | 
|  | 759 | /// } | 
|  | 760 | /// ``` | 
|  | 761 | #[macro_export] | 
|  | 762 | macro_rules! declare_binder_interface { | 
|  | 763 | { | 
|  | 764 | $interface:path[$descriptor:expr] { | 
|  | 765 | native: $native:ident($on_transact:path), | 
|  | 766 | proxy: $proxy:ident, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 767 | $(async: $async_interface:ident,)? | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 768 | } | 
|  | 769 | } => { | 
|  | 770 | $crate::declare_binder_interface! { | 
|  | 771 | $interface[$descriptor] { | 
|  | 772 | native: $native($on_transact), | 
|  | 773 | proxy: $proxy {}, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 774 | $(async: $async_interface,)? | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 775 | stability: $crate::binder_impl::Stability::default(), | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 776 | } | 
|  | 777 | } | 
|  | 778 | }; | 
|  | 779 |  | 
|  | 780 | { | 
|  | 781 | $interface:path[$descriptor:expr] { | 
|  | 782 | native: $native:ident($on_transact:path), | 
|  | 783 | proxy: $proxy:ident, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 784 | $(async: $async_interface:ident,)? | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 785 | stability: $stability:expr, | 
|  | 786 | } | 
|  | 787 | } => { | 
|  | 788 | $crate::declare_binder_interface! { | 
|  | 789 | $interface[$descriptor] { | 
|  | 790 | native: $native($on_transact), | 
|  | 791 | proxy: $proxy {}, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 792 | $(async: $async_interface,)? | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 793 | stability: $stability, | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 794 | } | 
|  | 795 | } | 
|  | 796 | }; | 
|  | 797 |  | 
|  | 798 | { | 
|  | 799 | $interface:path[$descriptor:expr] { | 
|  | 800 | native: $native:ident($on_transact:path), | 
|  | 801 | proxy: $proxy:ident { | 
|  | 802 | $($fname:ident: $fty:ty = $finit:expr),* | 
|  | 803 | }, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 804 | $(async: $async_interface:ident,)? | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 805 | } | 
|  | 806 | } => { | 
|  | 807 | $crate::declare_binder_interface! { | 
|  | 808 | $interface[$descriptor] { | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 809 | native: $native($on_transact), | 
|  | 810 | proxy: $proxy { | 
|  | 811 | $($fname: $fty = $finit),* | 
|  | 812 | }, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 813 | $(async: $async_interface,)? | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 814 | stability: $crate::binder_impl::Stability::default(), | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 815 | } | 
|  | 816 | } | 
|  | 817 | }; | 
|  | 818 |  | 
|  | 819 | { | 
|  | 820 | $interface:path[$descriptor:expr] { | 
|  | 821 | native: $native:ident($on_transact:path), | 
|  | 822 | proxy: $proxy:ident { | 
|  | 823 | $($fname:ident: $fty:ty = $finit:expr),* | 
|  | 824 | }, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 825 | $(async: $async_interface:ident,)? | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 826 | stability: $stability:expr, | 
|  | 827 | } | 
|  | 828 | } => { | 
|  | 829 | $crate::declare_binder_interface! { | 
|  | 830 | $interface[$descriptor] { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 831 | @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")] | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 832 | native: $native($on_transact), | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 833 | @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 834 | proxy: $proxy { | 
|  | 835 | $($fname: $fty = $finit),* | 
|  | 836 | }, | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 837 | $(async: $async_interface,)? | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 838 | stability: $stability, | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 839 | } | 
|  | 840 | } | 
|  | 841 | }; | 
|  | 842 |  | 
|  | 843 | { | 
|  | 844 | $interface:path[$descriptor:expr] { | 
|  | 845 | @doc[$native_doc:expr] | 
|  | 846 | native: $native:ident($on_transact:path), | 
|  | 847 |  | 
|  | 848 | @doc[$proxy_doc:expr] | 
|  | 849 | proxy: $proxy:ident { | 
|  | 850 | $($fname:ident: $fty:ty = $finit:expr),* | 
|  | 851 | }, | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 852 |  | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 853 | $( async: $async_interface:ident, )? | 
|  | 854 |  | 
| Stephen Crane | ff7f03a | 2021-02-25 16:04:22 -0800 | [diff] [blame] | 855 | stability: $stability:expr, | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 856 | } | 
|  | 857 | } => { | 
|  | 858 | #[doc = $proxy_doc] | 
|  | 859 | pub struct $proxy { | 
|  | 860 | binder: $crate::SpIBinder, | 
|  | 861 | $($fname: $fty,)* | 
|  | 862 | } | 
|  | 863 |  | 
|  | 864 | impl $crate::Interface for $proxy { | 
|  | 865 | fn as_binder(&self) -> $crate::SpIBinder { | 
|  | 866 | self.binder.clone() | 
|  | 867 | } | 
|  | 868 | } | 
|  | 869 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 870 | impl $crate::binder_impl::Proxy for $proxy | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 871 | where | 
|  | 872 | $proxy: $interface, | 
|  | 873 | { | 
|  | 874 | fn get_descriptor() -> &'static str { | 
|  | 875 | $descriptor | 
|  | 876 | } | 
|  | 877 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 878 | fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> { | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 879 | Ok(Self { binder, $($fname: $finit),* }) | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 880 | } | 
|  | 881 | } | 
|  | 882 |  | 
|  | 883 | #[doc = $native_doc] | 
|  | 884 | #[repr(transparent)] | 
|  | 885 | pub struct $native(Box<dyn $interface + Sync + Send + 'static>); | 
|  | 886 |  | 
|  | 887 | impl $native { | 
|  | 888 | /// Create a new binder service. | 
| Andrew Walbran | 88eca4f | 2021-04-13 14:26:01 +0000 | [diff] [blame] | 889 | pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 890 | let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability); | 
| Janis Danisevskis | 1323d51 | 2021-11-09 07:48:08 -0800 | [diff] [blame] | 891 | #[cfg(not(android_vndk))] | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 892 | $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 893 | $crate::Strong::new(Box::new(binder)) | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 894 | } | 
|  | 895 | } | 
|  | 896 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 897 | impl $crate::binder_impl::Remotable for $native { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 898 | fn get_descriptor() -> &'static str { | 
|  | 899 | $descriptor | 
|  | 900 | } | 
|  | 901 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 902 | 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 Homescu | 3281437 | 2020-08-20 15:36:08 -0700 | [diff] [blame] | 903 | match $on_transact(&*self.0, code, data, reply) { | 
|  | 904 | // The C++ backend converts UNEXPECTED_NULL into an exception | 
|  | 905 | Err($crate::StatusCode::UNEXPECTED_NULL) => { | 
|  | 906 | let status = $crate::Status::new_exception( | 
|  | 907 | $crate::ExceptionCode::NULL_POINTER, | 
|  | 908 | None, | 
|  | 909 | ); | 
|  | 910 | reply.write(&status) | 
|  | 911 | }, | 
|  | 912 | result => result | 
|  | 913 | } | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 914 | } | 
|  | 915 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 916 | fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> { | 
| Stephen Crane | 2a3297f | 2021-06-11 16:48:10 -0700 | [diff] [blame] | 917 | self.0.dump(file, args) | 
|  | 918 | } | 
|  | 919 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 920 | fn get_class() -> $crate::binder_impl::InterfaceClass { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 921 | static CLASS_INIT: std::sync::Once = std::sync::Once::new(); | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 922 | static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 923 |  | 
|  | 924 | CLASS_INIT.call_once(|| unsafe { | 
|  | 925 | // Safety: This assignment is guarded by the `CLASS_INIT` `Once` | 
|  | 926 | // variable, and therefore is thread-safe, as it can only occur | 
|  | 927 | // once. | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 928 | CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>()); | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 929 | }); | 
|  | 930 | unsafe { | 
|  | 931 | // Safety: The `CLASS` variable can only be mutated once, above, | 
|  | 932 | // and is subsequently safe to read from any thread. | 
|  | 933 | CLASS.unwrap() | 
|  | 934 | } | 
|  | 935 | } | 
|  | 936 | } | 
|  | 937 |  | 
|  | 938 | impl $crate::FromIBinder for dyn $interface { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 939 | fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> { | 
|  | 940 | use $crate::binder_impl::AssociateClass; | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 941 |  | 
|  | 942 | let existing_class = ibinder.get_class(); | 
|  | 943 | if let Some(class) = existing_class { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 944 | if class != <$native as $crate::binder_impl::Remotable>::get_class() && | 
|  | 945 | class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 946 | { | 
|  | 947 | // The binder object's descriptor string matches what we | 
|  | 948 | // expect. We still need to treat this local or already | 
|  | 949 | // associated object as remote, because we can't cast it | 
|  | 950 | // into a Rust service object without a matching class | 
|  | 951 | // pointer. | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 952 | return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 953 | } | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 954 | } | 
|  | 955 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 956 | if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { | 
|  | 957 | let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 958 | std::convert::TryFrom::try_from(ibinder.clone()); | 
|  | 959 | if let Ok(service) = service { | 
|  | 960 | // We were able to associate with our expected class and | 
|  | 961 | // the service is local. | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 962 | return Ok($crate::Strong::new(Box::new(service))); | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 963 | } else { | 
|  | 964 | // Service is remote | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 965 | return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 966 | } | 
| Matthew Maurer | f6b9ad9 | 2020-12-03 19:27:25 +0000 | [diff] [blame] | 967 | } | 
| Stephen Crane | 669deb6 | 2020-09-10 17:31:39 -0700 | [diff] [blame] | 968 |  | 
|  | 969 | Err($crate::StatusCode::BAD_TYPE.into()) | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 970 | } | 
|  | 971 | } | 
|  | 972 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 973 | impl $crate::binder_impl::Serialize for dyn $interface + '_ | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 974 | where | 
| Stephen Crane | d58bce0 | 2020-07-07 12:26:02 -0700 | [diff] [blame] | 975 | dyn $interface: $crate::Interface | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 976 | { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 977 | fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 978 | let binder = $crate::Interface::as_binder(self); | 
|  | 979 | parcel.write(&binder) | 
|  | 980 | } | 
|  | 981 | } | 
|  | 982 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 983 | impl $crate::binder_impl::SerializeOption for dyn $interface + '_ { | 
|  | 984 | fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 985 | parcel.write(&this.map($crate::Interface::as_binder)) | 
|  | 986 | } | 
|  | 987 | } | 
| Andrei Homescu | 2e3c147 | 2020-08-11 16:35:40 -0700 | [diff] [blame] | 988 |  | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 989 | impl std::fmt::Debug for dyn $interface + '_ { | 
| Andrei Homescu | 2e3c147 | 2020-08-11 16:35:40 -0700 | [diff] [blame] | 990 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 
|  | 991 | f.pad(stringify!($interface)) | 
|  | 992 | } | 
|  | 993 | } | 
| Andrei Homescu | 64ebd13 | 2020-08-07 22:12:48 -0700 | [diff] [blame] | 994 |  | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 995 | /// Convert a &dyn $interface to Strong<dyn $interface> | 
| Andrei Homescu | 64ebd13 | 2020-08-07 22:12:48 -0700 | [diff] [blame] | 996 | impl std::borrow::ToOwned for dyn $interface { | 
| Stephen Crane | ddb3e6d | 2020-12-18 13:27:22 -0800 | [diff] [blame] | 997 | type Owned = $crate::Strong<dyn $interface>; | 
| Andrei Homescu | 64ebd13 | 2020-08-07 22:12:48 -0700 | [diff] [blame] | 998 | fn to_owned(&self) -> Self::Owned { | 
|  | 999 | self.as_binder().into_interface() | 
|  | 1000 | .expect(concat!("Error cloning interface ", stringify!($interface))) | 
|  | 1001 | } | 
|  | 1002 | } | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1003 |  | 
|  | 1004 | $( | 
|  | 1005 | // Async interface trait implementations. | 
|  | 1006 | impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1007 | fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> { | 
|  | 1008 | use $crate::binder_impl::AssociateClass; | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1009 |  | 
|  | 1010 | let existing_class = ibinder.get_class(); | 
|  | 1011 | if let Some(class) = existing_class { | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1012 | if class != <$native as $crate::binder_impl::Remotable>::get_class() && | 
|  | 1013 | class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1014 | { | 
|  | 1015 | // The binder object's descriptor string matches what we | 
|  | 1016 | // expect. We still need to treat this local or already | 
|  | 1017 | // associated object as remote, because we can't cast it | 
|  | 1018 | // into a Rust service object without a matching class | 
|  | 1019 | // pointer. | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1020 | return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1021 | } | 
|  | 1022 | } | 
|  | 1023 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1024 | if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { | 
|  | 1025 | let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1026 | std::convert::TryFrom::try_from(ibinder.clone()); | 
|  | 1027 | if let Ok(service) = service { | 
|  | 1028 | // We were able to associate with our expected class and | 
|  | 1029 | // the service is local. | 
|  | 1030 | todo!() | 
|  | 1031 | //return Ok($crate::Strong::new(Box::new(service))); | 
|  | 1032 | } else { | 
|  | 1033 | // Service is remote | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1034 | return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1035 | } | 
|  | 1036 | } | 
|  | 1037 |  | 
|  | 1038 | Err($crate::StatusCode::BAD_TYPE.into()) | 
|  | 1039 | } | 
|  | 1040 | } | 
|  | 1041 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1042 | impl<P: $crate::BinderAsyncPool> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ { | 
|  | 1043 | fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1044 | let binder = $crate::Interface::as_binder(self); | 
|  | 1045 | parcel.write(&binder) | 
|  | 1046 | } | 
|  | 1047 | } | 
|  | 1048 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1049 | impl<P: $crate::BinderAsyncPool> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ { | 
|  | 1050 | fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1051 | parcel.write(&this.map($crate::Interface::as_binder)) | 
|  | 1052 | } | 
|  | 1053 | } | 
|  | 1054 |  | 
|  | 1055 | impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ { | 
|  | 1056 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 
|  | 1057 | f.pad(stringify!($async_interface)) | 
|  | 1058 | } | 
|  | 1059 | } | 
|  | 1060 |  | 
|  | 1061 | /// Convert a &dyn $async_interface to Strong<dyn $async_interface> | 
|  | 1062 | impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> { | 
|  | 1063 | type Owned = $crate::Strong<dyn $async_interface<P>>; | 
|  | 1064 | fn to_owned(&self) -> Self::Owned { | 
|  | 1065 | self.as_binder().into_interface() | 
|  | 1066 | .expect(concat!("Error cloning interface ", stringify!($async_interface))) | 
|  | 1067 | } | 
|  | 1068 | } | 
| Alice Ryhl | c173684 | 2021-11-23 12:38:51 +0000 | [diff] [blame] | 1069 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1070 | impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface { | 
| Alice Ryhl | c173684 | 2021-11-23 12:38:51 +0000 | [diff] [blame] | 1071 | type Target = dyn $async_interface<P>; | 
|  | 1072 | } | 
|  | 1073 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1074 | impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> { | 
| Alice Ryhl | c173684 | 2021-11-23 12:38:51 +0000 | [diff] [blame] | 1075 | type Target = dyn $interface; | 
|  | 1076 | } | 
| Alice Ryhl | 05f5a2c | 2021-09-15 12:56:10 +0000 | [diff] [blame] | 1077 | )? | 
| Stephen Crane | 2a3c250 | 2020-06-16 17:48:35 -0700 | [diff] [blame] | 1078 | }; | 
|  | 1079 | } | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1080 |  | 
|  | 1081 | /// Declare an AIDL enumeration. | 
|  | 1082 | /// | 
|  | 1083 | /// This is mainly used internally by the AIDL compiler. | 
|  | 1084 | #[macro_export] | 
|  | 1085 | macro_rules! declare_binder_enum { | 
|  | 1086 | { | 
| Stephen Crane | 7bca105 | 2021-10-25 17:52:51 -0700 | [diff] [blame] | 1087 | $( #[$attr:meta] )* | 
| Andrei Homescu | 7f38cf9 | 2021-06-29 23:55:43 +0000 | [diff] [blame] | 1088 | $enum:ident : [$backing:ty; $size:expr] { | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1089 | $( $name:ident = $value:expr, )* | 
|  | 1090 | } | 
|  | 1091 | } => { | 
| Stephen Crane | 7bca105 | 2021-10-25 17:52:51 -0700 | [diff] [blame] | 1092 | $( #[$attr] )* | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1093 | #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] | 
| Stephen Crane | 7bca105 | 2021-10-25 17:52:51 -0700 | [diff] [blame] | 1094 | #[allow(missing_docs)] | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1095 | pub struct $enum(pub $backing); | 
|  | 1096 | impl $enum { | 
| Stephen Crane | 7bca105 | 2021-10-25 17:52:51 -0700 | [diff] [blame] | 1097 | $( #[allow(missing_docs)] pub const $name: Self = Self($value); )* | 
| Andrei Homescu | 7f38cf9 | 2021-06-29 23:55:43 +0000 | [diff] [blame] | 1098 |  | 
|  | 1099 | #[inline(always)] | 
| Stephen Crane | 7bca105 | 2021-10-25 17:52:51 -0700 | [diff] [blame] | 1100 | #[allow(missing_docs)] | 
| Andrei Homescu | 7f38cf9 | 2021-06-29 23:55:43 +0000 | [diff] [blame] | 1101 | pub const fn enum_values() -> [Self; $size] { | 
|  | 1102 | [$(Self::$name),*] | 
|  | 1103 | } | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1104 | } | 
|  | 1105 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1106 | impl $crate::binder_impl::Serialize for $enum { | 
|  | 1107 | fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1108 | parcel.write(&self.0) | 
|  | 1109 | } | 
|  | 1110 | } | 
|  | 1111 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1112 | impl $crate::binder_impl::SerializeArray for $enum { | 
|  | 1113 | fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1114 | let v: Vec<$backing> = slice.iter().map(|x| x.0).collect(); | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1115 | <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel) | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1116 | } | 
|  | 1117 | } | 
|  | 1118 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1119 | impl $crate::binder_impl::Deserialize for $enum { | 
|  | 1120 | fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> { | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1121 | parcel.read().map(Self) | 
|  | 1122 | } | 
|  | 1123 | } | 
|  | 1124 |  | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1125 | impl $crate::binder_impl::DeserializeArray for $enum { | 
|  | 1126 | fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> { | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1127 | let v: Option<Vec<$backing>> = | 
| Stephen Crane | f2735b4 | 2022-01-19 17:49:46 +0000 | [diff] [blame] | 1128 | <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?; | 
| Andrei Homescu | 00eca71 | 2020-09-09 18:57:40 -0700 | [diff] [blame] | 1129 | Ok(v.map(|v| v.into_iter().map(Self).collect())) | 
|  | 1130 | } | 
|  | 1131 | } | 
|  | 1132 | }; | 
|  | 1133 | } |