blob: 8ae010ea8805b9b5fd22e6e0ad3ac3d68c4dd16f [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
Alan Stokes23fdfcd2021-09-09 11:19:24 +010017use crate::binder::{
18 AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode,
19};
Stephen Crane2a3c2502020-06-16 17:48:35 -070020use crate::error::{status_result, status_t, Result, StatusCode};
Alice Ryhl8618c482021-11-09 15:35:35 +000021use crate::parcel::{BorrowedParcel, Serialize};
Stephen Crane2a3c2502020-06-16 17:48:35 -070022use crate::proxy::SpIBinder;
23use crate::sys;
24
25use std::convert::TryFrom;
Stephen Crane2a3297f2021-06-11 16:48:10 -070026use std::ffi::{c_void, CStr, CString};
Andrei Homescud23c0492023-11-09 01:51:59 +000027use std::io::Write;
Stephen Crane2a3c2502020-06-16 17:48:35 -070028use std::mem::ManuallyDrop;
29use std::ops::Deref;
Stephen Crane2a3297f2021-06-11 16:48:10 -070030use std::os::raw::c_char;
Andrew Walbran7b0be1f2022-08-04 16:47:46 +000031use std::sync::Mutex;
Stephen Crane2a3c2502020-06-16 17:48:35 -070032
33/// Rust wrapper around Binder remotable objects.
34///
35/// Implements the C++ `BBinder` class, and therefore implements the C++
36/// `IBinder` interface.
37#[repr(C)]
38pub struct Binder<T: Remotable> {
39 ibinder: *mut sys::AIBinder,
40 rust_object: *mut T,
41}
42
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010043/// Safety:
Andrei Homescu2c674b02020-08-07 22:12:27 -070044///
45/// A `Binder<T>` is a pair of unique owning pointers to two values:
46/// * a C++ ABBinder which the C++ API guarantees can be passed between threads
47/// * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
48///
49/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
50/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
51/// the box-like object inherits `Send` from the two inner values, similarly
52/// to how `Box<T>` is `Send` if `T` is `Send`.
53unsafe impl<T: Remotable> Send for Binder<T> {}
54
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010055/// Safety:
Stephen Cranef03fe3d2021-06-25 15:05:00 -070056///
57/// A `Binder<T>` is a pair of unique owning pointers to two values:
58/// * a C++ ABBinder which is thread-safe, i.e. `Send + Sync`
59/// * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
60///
61/// `ABBinder` contains an immutable `mUserData` pointer, which is actually a
62/// pointer to a boxed `T: Remotable`, which is `Sync`. `ABBinder` also contains
63/// a mutable pointer to its class, but mutation of this field is controlled by
64/// a mutex and it is only allowed to be set once, therefore we can concurrently
65/// access this field safely. `ABBinder` inherits from `BBinder`, which is also
66/// thread-safe. Thus `ABBinder` is thread-safe.
67///
68/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
69/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
70/// the box-like object inherits `Sync` from the two inner values, similarly
71/// to how `Box<T>` is `Sync` if `T` is `Sync`.
72unsafe impl<T: Remotable> Sync for Binder<T> {}
73
Stephen Crane2a3c2502020-06-16 17:48:35 -070074impl<T: Remotable> Binder<T> {
Stephen Craneff7f03a2021-02-25 16:04:22 -080075 /// Create a new Binder remotable object with default stability
Stephen Crane2a3c2502020-06-16 17:48:35 -070076 ///
77 /// This moves the `rust_object` into an owned [`Box`] and Binder will
78 /// manage its lifetime.
79 pub fn new(rust_object: T) -> Binder<T> {
Stephen Craneff7f03a2021-02-25 16:04:22 -080080 Self::new_with_stability(rust_object, Stability::default())
81 }
82
83 /// Create a new Binder remotable object with the given stability
84 ///
85 /// This moves the `rust_object` into an owned [`Box`] and Binder will
86 /// manage its lifetime.
87 pub fn new_with_stability(rust_object: T, stability: Stability) -> Binder<T> {
Stephen Crane2a3c2502020-06-16 17:48:35 -070088 let class = T::get_class();
89 let rust_object = Box::into_raw(Box::new(rust_object));
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010090 // Safety: `AIBinder_new` expects a valid class pointer (which we
91 // initialize via `get_class`), and an arbitrary pointer
92 // argument. The caller owns the returned `AIBinder` pointer, which
93 // is a strong reference to a `BBinder`. This reference should be
94 // decremented via `AIBinder_decStrong` when the reference lifetime
95 // ends.
96 let ibinder = unsafe { sys::AIBinder_new(class.into(), rust_object as *mut c_void) };
Matthew Maurere268a9f2022-07-26 09:31:30 -070097 let mut binder = Binder { ibinder, rust_object };
Stephen Craneff7f03a2021-02-25 16:04:22 -080098 binder.mark_stability(stability);
99 binder
Stephen Crane2a3c2502020-06-16 17:48:35 -0700100 }
101
102 /// Set the extension of a binder interface. This allows a downstream
103 /// developer to add an extension to an interface without modifying its
104 /// interface file. This should be called immediately when the object is
105 /// created before it is passed to another thread.
106 ///
107 /// # Examples
108 ///
109 /// For instance, imagine if we have this Binder AIDL interface definition:
110 /// interface IFoo { void doFoo(); }
111 ///
112 /// If an unrelated owner (perhaps in a downstream codebase) wants to make a
113 /// change to the interface, they have two options:
114 ///
115 /// 1) Historical option that has proven to be BAD! Only the original
116 /// author of an interface should change an interface. If someone
117 /// downstream wants additional functionality, they should not ever
118 /// change the interface or use this method.
119 /// ```AIDL
120 /// BAD TO DO: interface IFoo { BAD TO DO
121 /// BAD TO DO: void doFoo(); BAD TO DO
122 /// BAD TO DO: + void doBar(); // adding a method BAD TO DO
123 /// BAD TO DO: } BAD TO DO
124 /// ```
125 ///
126 /// 2) Option that this method enables!
127 /// Leave the original interface unchanged (do not change IFoo!).
128 /// Instead, create a new AIDL interface in a downstream package:
129 /// ```AIDL
130 /// package com.<name>; // new functionality in a new package
131 /// interface IBar { void doBar(); }
132 /// ```
133 ///
134 /// When registering the interface, add:
135 ///
136 /// # use binder::{Binder, Interface};
137 /// # type MyFoo = ();
138 /// # type MyBar = ();
139 /// # let my_foo = ();
140 /// # let my_bar = ();
141 /// let mut foo: Binder<MyFoo> = Binder::new(my_foo); // class in AOSP codebase
142 /// let bar: Binder<MyBar> = Binder::new(my_bar); // custom extension class
143 /// foo.set_extension(&mut bar.as_binder()); // use method in Binder
144 ///
145 /// Then, clients of `IFoo` can get this extension:
146 ///
147 /// # use binder::{declare_binder_interface, Binder, TransactionCode, Parcel};
148 /// # trait IBar {}
149 /// # declare_binder_interface! {
150 /// # IBar["test"] {
151 /// # native: BnBar(on_transact),
152 /// # proxy: BpBar,
153 /// # }
154 /// # }
155 /// # fn on_transact(
156 /// # service: &dyn IBar,
157 /// # code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000158 /// # data: &BorrowedParcel,
159 /// # reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700160 /// # ) -> binder::Result<()> {
161 /// # Ok(())
162 /// # }
163 /// # impl IBar for BpBar {}
164 /// # impl IBar for Binder<BnBar> {}
165 /// # fn main() -> binder::Result<()> {
166 /// # let binder = Binder::new(());
167 /// if let Some(barBinder) = binder.get_extension()? {
168 /// let bar = BpBar::new(barBinder)
169 /// .expect("Extension was not of type IBar");
170 /// } else {
171 /// // There was no extension
172 /// }
173 /// # }
174 pub fn set_extension(&mut self, extension: &mut SpIBinder) -> Result<()> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100175 let status =
176 // Safety: `AIBinder_setExtension` expects two valid, mutable
177 // `AIBinder` pointers. We are guaranteed that both `self` and
178 // `extension` contain valid `AIBinder` pointers, because they
179 // cannot be initialized without a valid
180 // pointer. `AIBinder_setExtension` does not take ownership of
181 // either parameter.
182 unsafe { sys::AIBinder_setExtension(self.as_native_mut(), extension.as_native_mut()) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700183 status_result(status)
184 }
185
186 /// Retrieve the interface descriptor string for this object's Binder
187 /// interface.
188 pub fn get_descriptor() -> &'static str {
189 T::get_descriptor()
190 }
Stephen Craneff7f03a2021-02-25 16:04:22 -0800191
192 /// Mark this binder object with the given stability guarantee
193 fn mark_stability(&mut self, stability: Stability) {
194 match stability {
195 Stability::Local => self.mark_local_stability(),
196 Stability::Vintf => {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100197 // Safety: Self always contains a valid `AIBinder` pointer, so
198 // we can always call this C API safely.
Stephen Craneff7f03a2021-02-25 16:04:22 -0800199 unsafe {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800200 sys::AIBinder_markVintfStability(self.as_native_mut());
201 }
202 }
203 }
204 }
205
206 /// Mark this binder object with local stability, which is vendor if we are
Devin Moore3d5ca6b2023-02-17 02:10:50 +0000207 /// building for android_vendor and system otherwise.
208 #[cfg(android_vendor)]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800209 fn mark_local_stability(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100210 // Safety: Self always contains a valid `AIBinder` pointer, so we can
211 // always call this C API safely.
Stephen Craneff7f03a2021-02-25 16:04:22 -0800212 unsafe {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800213 sys::AIBinder_markVendorStability(self.as_native_mut());
214 }
215 }
216
217 /// Mark this binder object with local stability, which is vendor if we are
Devin Moore3d5ca6b2023-02-17 02:10:50 +0000218 /// building for android_vendor and system otherwise.
219 #[cfg(not(android_vendor))]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800220 fn mark_local_stability(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100221 // Safety: Self always contains a valid `AIBinder` pointer, so we can
222 // always call this C API safely.
Stephen Craneff7f03a2021-02-25 16:04:22 -0800223 unsafe {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800224 sys::AIBinder_markSystemStability(self.as_native_mut());
225 }
226 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700227}
228
229impl<T: Remotable> Interface for Binder<T> {
230 /// Converts the local remotable object into a generic `SpIBinder`
231 /// reference.
232 ///
233 /// The resulting `SpIBinder` will hold its own strong reference to this
234 /// remotable object, which will prevent the object from being dropped while
235 /// the `SpIBinder` is alive.
236 fn as_binder(&self) -> SpIBinder {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100237 // Safety: `self.ibinder` is guaranteed to always be a valid pointer
238 // to an `AIBinder` by the `Binder` constructor. We are creating a
239 // copy of the `self.ibinder` strong reference, but
240 // `SpIBinder::from_raw` assumes it receives an owned pointer with
241 // its own strong reference. We first increment the reference count,
242 // so that the new `SpIBinder` will be tracked as a new reference.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700243 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700244 sys::AIBinder_incStrong(self.ibinder);
245 SpIBinder::from_raw(self.ibinder).unwrap()
246 }
247 }
248}
249
250impl<T: Remotable> InterfaceClassMethods for Binder<T> {
251 fn get_descriptor() -> &'static str {
252 <T as Remotable>::get_descriptor()
253 }
254
255 /// Called whenever a transaction needs to be processed by a local
256 /// implementation.
257 ///
258 /// # Safety
259 ///
260 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
261 /// contains a `T` pointer in its user data. The `data` and `reply` parcel
262 /// parameters must be valid pointers to `AParcel` objects. This method does
263 /// not take ownership of any of its parameters.
264 ///
265 /// These conditions hold when invoked by `ABBinder::onTransact`.
266 unsafe extern "C" fn on_transact(
267 binder: *mut sys::AIBinder,
268 code: u32,
269 data: *const sys::AParcel,
270 reply: *mut sys::AParcel,
271 ) -> status_t {
272 let res = {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100273 // Safety: The caller must give us a parcel pointer which is either
274 // null or valid at least for the duration of this function call. We
275 // don't keep the resulting value beyond the function.
276 let mut reply = unsafe { BorrowedParcel::from_raw(reply).unwrap() };
277 // Safety: The caller must give us a parcel pointer which is either
278 // null or valid at least for the duration of this function call. We
279 // don't keep the resulting value beyond the function.
280 let data = unsafe { BorrowedParcel::from_raw(data as *mut sys::AParcel).unwrap() };
281 // Safety: Our caller promised that `binder` is a non-null, valid
282 // pointer to a local `AIBinder`.
283 let object = unsafe { sys::AIBinder_getUserData(binder) };
284 // Safety: Our caller promised that the binder has a `T` pointer in
285 // its user data.
286 let binder: &T = unsafe { &*(object as *const T) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700287 binder.on_transact(code, &data, &mut reply)
288 };
289 match res {
290 Ok(()) => 0i32,
291 Err(e) => e as i32,
292 }
293 }
294
295 /// Called whenever an `AIBinder` object is no longer referenced and needs
296 /// destroyed.
297 ///
298 /// # Safety
299 ///
300 /// Must be called with a valid pointer to a `T` object. After this call,
301 /// the pointer will be invalid and should not be dereferenced.
302 unsafe extern "C" fn on_destroy(object: *mut c_void) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100303 // Safety: Our caller promised that `object` is a valid pointer to a
304 // `T`.
305 drop(unsafe { Box::from_raw(object as *mut T) });
Stephen Crane2a3c2502020-06-16 17:48:35 -0700306 }
307
308 /// Called whenever a new, local `AIBinder` object is needed of a specific
309 /// class.
310 ///
311 /// Constructs the user data pointer that will be stored in the object,
312 /// which will be a heap-allocated `T` object.
313 ///
314 /// # Safety
315 ///
316 /// Must be called with a valid pointer to a `T` object allocated via `Box`.
317 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void {
318 // We just return the argument, as it is already a pointer to the rust
319 // object created by Box.
320 args
321 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700322
323 /// Called to handle the `dump` transaction.
324 ///
325 /// # Safety
326 ///
327 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
328 /// contains a `T` pointer in its user data. fd should be a non-owned file
329 /// descriptor, and args must be an array of null-terminated string
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100330 /// pointers with length num_args.
Andrei Homescu4b21b9f2023-05-09 02:50:37 +0000331 #[cfg(not(target_os = "trusty"))]
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100332 unsafe extern "C" fn on_dump(
333 binder: *mut sys::AIBinder,
334 fd: i32,
335 args: *mut *const c_char,
336 num_args: u32,
337 ) -> status_t {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700338 if fd < 0 {
339 return StatusCode::UNEXPECTED_NULL as status_t;
340 }
Andrei Homescu4b21b9f2023-05-09 02:50:37 +0000341 use std::os::fd::FromRawFd;
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100342 // Safety: Our caller promised that fd is a file descriptor. We don't
343 // own this file descriptor, so we need to be careful not to drop it.
Andrei Homescu4b21b9f2023-05-09 02:50:37 +0000344 let mut file = unsafe { ManuallyDrop::new(std::fs::File::from_raw_fd(fd)) };
Stephen Crane2a3297f2021-06-11 16:48:10 -0700345
Stephen Crane0c5f9232022-06-17 11:48:05 -0700346 if args.is_null() && num_args != 0 {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700347 return StatusCode::UNEXPECTED_NULL as status_t;
348 }
Stephen Crane0c5f9232022-06-17 11:48:05 -0700349
350 let args = if args.is_null() || num_args == 0 {
351 vec![]
352 } else {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100353 // Safety: Our caller promised that `args` is an array of
354 // null-terminated string pointers with length `num_args`.
355 unsafe {
Andrei Homescu4b21b9f2023-05-09 02:50:37 +0000356 std::slice::from_raw_parts(args, num_args as usize)
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100357 .iter()
358 .map(|s| CStr::from_ptr(*s))
359 .collect()
360 }
Stephen Crane0c5f9232022-06-17 11:48:05 -0700361 };
Stephen Crane2a3297f2021-06-11 16:48:10 -0700362
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100363 // Safety: Our caller promised that `binder` is a non-null, valid
364 // pointer to a local `AIBinder`.
365 let object = unsafe { sys::AIBinder_getUserData(binder) };
366 // Safety: Our caller promised that the binder has a `T` pointer in its
367 // user data.
368 let binder: &T = unsafe { &*(object as *const T) };
Andrei Homescud23c0492023-11-09 01:51:59 +0000369 let res = binder.on_dump(&mut *file, &args);
Stephen Crane2a3297f2021-06-11 16:48:10 -0700370
371 match res {
372 Ok(()) => 0,
373 Err(e) => e as status_t,
374 }
375 }
Andrei Homescu4b21b9f2023-05-09 02:50:37 +0000376
377 /// Called to handle the `dump` transaction.
378 #[cfg(target_os = "trusty")]
379 unsafe extern "C" fn on_dump(
380 _binder: *mut sys::AIBinder,
381 _fd: i32,
382 _args: *mut *const c_char,
383 _num_args: u32,
384 ) -> status_t {
385 // This operation is not supported on Trusty right now
386 // because we do not have a uniform way of writing to handles
387 StatusCode::INVALID_OPERATION as status_t
388 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700389}
390
391impl<T: Remotable> Drop for Binder<T> {
392 // This causes C++ to decrease the strong ref count of the `AIBinder`
393 // object. We specifically do not drop the `rust_object` here. When C++
394 // actually destroys the object, it calls `on_destroy` and we can drop the
395 // `rust_object` then.
396 fn drop(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100397 // Safety: When `self` is dropped, we can no longer access the
398 // reference, so can decrement the reference count. `self.ibinder` is
399 // always a valid `AIBinder` pointer, so is valid to pass to
400 // `AIBinder_decStrong`.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700401 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700402 sys::AIBinder_decStrong(self.ibinder);
403 }
404 }
405}
406
407impl<T: Remotable> Deref for Binder<T> {
408 type Target = T;
409
410 fn deref(&self) -> &Self::Target {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100411 // Safety: While `self` is alive, the reference count of the underlying
412 // object is > 0 and therefore `on_destroy` cannot be called. Therefore
413 // while `self` is alive, we know that `rust_object` is still a valid
414 // pointer to a heap allocated object of type `T`.
415 unsafe { &*self.rust_object }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700416 }
417}
418
419impl<B: Remotable> Serialize for Binder<B> {
Alice Ryhl8618c482021-11-09 15:35:35 +0000420 fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700421 parcel.write_binder(Some(&self.as_binder()))
422 }
423}
424
425// This implementation is an idiomatic implementation of the C++
426// `IBinder::localBinder` interface if the binder object is a Rust binder
427// service.
428impl<B: Remotable> TryFrom<SpIBinder> for Binder<B> {
429 type Error = StatusCode;
430
431 fn try_from(mut ibinder: SpIBinder) -> Result<Self> {
432 let class = B::get_class();
433 if Some(class) != ibinder.get_class() {
434 return Err(StatusCode::BAD_TYPE);
435 }
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100436 // Safety: `SpIBinder` always holds a valid pointer pointer to an
437 // `AIBinder`, which we can safely pass to `AIBinder_getUserData`.
438 // `ibinder` retains ownership of the returned pointer.
439 let userdata = unsafe { sys::AIBinder_getUserData(ibinder.as_native_mut()) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700440 if userdata.is_null() {
441 return Err(StatusCode::UNEXPECTED_NULL);
442 }
443 // We are transferring the ownership of the AIBinder into the new Binder
444 // object.
445 let mut ibinder = ManuallyDrop::new(ibinder);
Matthew Maurere268a9f2022-07-26 09:31:30 -0700446 Ok(Binder { ibinder: ibinder.as_native_mut(), rust_object: userdata as *mut B })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700447 }
448}
449
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100450/// Safety: The constructor for `Binder` guarantees that `self.ibinder` will
451/// contain a valid, non-null pointer to an `AIBinder`, so this implementation
452/// is type safe. `self.ibinder` will remain valid for the entire lifetime of
453/// `self` because we hold a strong reference to the `AIBinder` until `self` is
Stephen Crane2a3c2502020-06-16 17:48:35 -0700454/// dropped.
455unsafe impl<B: Remotable> AsNative<sys::AIBinder> for Binder<B> {
456 fn as_native(&self) -> *const sys::AIBinder {
457 self.ibinder
458 }
459
460 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
461 self.ibinder
462 }
463}
464
465/// Register a new service with the default service manager.
466///
467/// Registers the given binder object with the given identifier. If successful,
468/// this service can then be retrieved using that identifier.
Alan Stokes1a49e4f2021-09-23 10:30:47 +0100469///
470/// This function will panic if the identifier contains a 0 byte (NUL).
Stephen Crane2a3c2502020-06-16 17:48:35 -0700471pub fn add_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
472 let instance = CString::new(identifier).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100473 let status =
474 // Safety: `AServiceManager_addService` expects valid `AIBinder` and C
475 // string pointers. Caller retains ownership of both pointers.
476 // `AServiceManager_addService` creates a new strong reference and copies
477 // the string, so both pointers need only be valid until the call returns.
478 unsafe { sys::AServiceManager_addService(binder.as_native_mut(), instance.as_ptr()) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700479 status_result(status)
480}
481
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100482/// Register a dynamic service via the LazyServiceRegistrar.
483///
484/// Registers the given binder object with the given identifier. If successful,
485/// this service can then be retrieved using that identifier. The service process
486/// will be shut down once all registered services are no longer in use.
487///
488/// If any service in the process is registered as lazy, all should be, otherwise
489/// the process may be shut down while a service is in use.
Alan Stokes1a49e4f2021-09-23 10:30:47 +0100490///
491/// This function will panic if the identifier contains a 0 byte (NUL).
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100492pub fn register_lazy_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
493 let instance = CString::new(identifier).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100494 // Safety: `AServiceManager_registerLazyService` expects valid `AIBinder` and C
495 // string pointers. Caller retains ownership of both
496 // pointers. `AServiceManager_registerLazyService` creates a new strong reference
497 // and copies the string, so both pointers need only be valid until the
498 // call returns.
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100499 let status = unsafe {
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100500 sys::AServiceManager_registerLazyService(binder.as_native_mut(), instance.as_ptr())
501 };
502 status_result(status)
503}
504
505/// Prevent a process which registers lazy services from being shut down even when none
506/// of the services is in use.
507///
508/// If persist is true then shut down will be blocked until this function is called again with
509/// persist false. If this is to be the initial state, call this function before calling
510/// register_lazy_service.
Andrew Walbran7b0be1f2022-08-04 16:47:46 +0000511///
512/// Consider using [`LazyServiceGuard`] rather than calling this directly.
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100513pub fn force_lazy_services_persist(persist: bool) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100514 // Safety: No borrowing or transfer of ownership occurs here.
515 unsafe { sys::AServiceManager_forceLazyServicesPersist(persist) }
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100516}
517
Andrew Walbran7b0be1f2022-08-04 16:47:46 +0000518/// An RAII object to ensure a process which registers lazy services is not killed. During the
519/// lifetime of any of these objects the service manager will not not kill the process even if none
520/// of its lazy services are in use.
521#[must_use]
522#[derive(Debug)]
523pub struct LazyServiceGuard {
524 // Prevent construction outside this module.
525 _private: (),
526}
527
Andrew Walbran3a957462022-08-24 10:55:16 +0000528// Count of how many LazyServiceGuard objects are in existence.
529static GUARD_COUNT: Mutex<u64> = Mutex::new(0);
Andrew Walbran7b0be1f2022-08-04 16:47:46 +0000530
531impl LazyServiceGuard {
532 /// Create a new LazyServiceGuard to prevent the service manager prematurely killing this
533 /// process.
534 pub fn new() -> Self {
535 let mut count = GUARD_COUNT.lock().unwrap();
536 *count += 1;
537 if *count == 1 {
538 // It's important that we make this call with the mutex held, to make sure
539 // that multiple calls (e.g. if the count goes 1 -> 0 -> 1) are correctly
540 // sequenced. (That also means we can't just use an AtomicU64.)
541 force_lazy_services_persist(true);
542 }
543 Self { _private: () }
544 }
545}
546
547impl Drop for LazyServiceGuard {
548 fn drop(&mut self) {
549 let mut count = GUARD_COUNT.lock().unwrap();
550 *count -= 1;
551 if *count == 0 {
552 force_lazy_services_persist(false);
553 }
554 }
555}
556
557impl Clone for LazyServiceGuard {
558 fn clone(&self) -> Self {
559 Self::new()
560 }
561}
562
563impl Default for LazyServiceGuard {
564 fn default() -> Self {
565 Self::new()
566 }
567}
568
Stephen Crane2a3c2502020-06-16 17:48:35 -0700569/// Tests often create a base BBinder instance; so allowing the unit
570/// type to be remotable translates nicely to Binder::new(()).
571impl Remotable for () {
572 fn get_descriptor() -> &'static str {
573 ""
574 }
575
576 fn on_transact(
577 &self,
578 _code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000579 _data: &BorrowedParcel<'_>,
580 _reply: &mut BorrowedParcel<'_>,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700581 ) -> Result<()> {
582 Ok(())
583 }
584
Andrei Homescud23c0492023-11-09 01:51:59 +0000585 fn on_dump(&self, _writer: &mut dyn Write, _args: &[&CStr]) -> Result<()> {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700586 Ok(())
587 }
588
Stephen Crane2a3c2502020-06-16 17:48:35 -0700589 binder_fn_get_class!(Binder::<Self>);
590}
591
592impl Interface for () {}
Alice Ryhlad9c77b2021-11-16 09:49:29 +0000593
594/// Determine whether the current thread is currently executing an incoming
595/// transaction.
596pub fn is_handling_transaction() -> bool {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100597 // Safety: This method is always safe to call.
598 unsafe { sys::AIBinder_isHandlingTransaction() }
Alice Ryhlad9c77b2021-11-16 09:49:29 +0000599}