blob: b248f5eb28afd33ab9dc2a9a67dc86beb13a33ba [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};
27use std::fs::File;
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;
31use std::os::unix::io::FromRawFd;
32use std::slice;
Andrew Walbran7b0be1f2022-08-04 16:47:46 +000033use std::sync::Mutex;
Stephen Crane2a3c2502020-06-16 17:48:35 -070034
35/// Rust wrapper around Binder remotable objects.
36///
37/// Implements the C++ `BBinder` class, and therefore implements the C++
38/// `IBinder` interface.
39#[repr(C)]
40pub struct Binder<T: Remotable> {
41 ibinder: *mut sys::AIBinder,
42 rust_object: *mut T,
43}
44
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010045/// Safety:
Andrei Homescu2c674b02020-08-07 22:12:27 -070046///
47/// A `Binder<T>` is a pair of unique owning pointers to two values:
48/// * a C++ ABBinder which the C++ API guarantees can be passed between threads
49/// * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
50///
51/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
52/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
53/// the box-like object inherits `Send` from the two inner values, similarly
54/// to how `Box<T>` is `Send` if `T` is `Send`.
55unsafe impl<T: Remotable> Send for Binder<T> {}
56
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010057/// Safety:
Stephen Cranef03fe3d2021-06-25 15:05:00 -070058///
59/// A `Binder<T>` is a pair of unique owning pointers to two values:
60/// * a C++ ABBinder which is thread-safe, i.e. `Send + Sync`
61/// * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
62///
63/// `ABBinder` contains an immutable `mUserData` pointer, which is actually a
64/// pointer to a boxed `T: Remotable`, which is `Sync`. `ABBinder` also contains
65/// a mutable pointer to its class, but mutation of this field is controlled by
66/// a mutex and it is only allowed to be set once, therefore we can concurrently
67/// access this field safely. `ABBinder` inherits from `BBinder`, which is also
68/// thread-safe. Thus `ABBinder` is thread-safe.
69///
70/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
71/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
72/// the box-like object inherits `Sync` from the two inner values, similarly
73/// to how `Box<T>` is `Sync` if `T` is `Sync`.
74unsafe impl<T: Remotable> Sync for Binder<T> {}
75
Stephen Crane2a3c2502020-06-16 17:48:35 -070076impl<T: Remotable> Binder<T> {
Stephen Craneff7f03a2021-02-25 16:04:22 -080077 /// Create a new Binder remotable object with default stability
Stephen Crane2a3c2502020-06-16 17:48:35 -070078 ///
79 /// This moves the `rust_object` into an owned [`Box`] and Binder will
80 /// manage its lifetime.
81 pub fn new(rust_object: T) -> Binder<T> {
Stephen Craneff7f03a2021-02-25 16:04:22 -080082 Self::new_with_stability(rust_object, Stability::default())
83 }
84
85 /// Create a new Binder remotable object with the given stability
86 ///
87 /// This moves the `rust_object` into an owned [`Box`] and Binder will
88 /// manage its lifetime.
89 pub fn new_with_stability(rust_object: T, stability: Stability) -> Binder<T> {
Stephen Crane2a3c2502020-06-16 17:48:35 -070090 let class = T::get_class();
91 let rust_object = Box::into_raw(Box::new(rust_object));
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +010092 // Safety: `AIBinder_new` expects a valid class pointer (which we
93 // initialize via `get_class`), and an arbitrary pointer
94 // argument. The caller owns the returned `AIBinder` pointer, which
95 // is a strong reference to a `BBinder`. This reference should be
96 // decremented via `AIBinder_decStrong` when the reference lifetime
97 // ends.
98 let ibinder = unsafe { sys::AIBinder_new(class.into(), rust_object as *mut c_void) };
Matthew Maurere268a9f2022-07-26 09:31:30 -070099 let mut binder = Binder { ibinder, rust_object };
Stephen Craneff7f03a2021-02-25 16:04:22 -0800100 binder.mark_stability(stability);
101 binder
Stephen Crane2a3c2502020-06-16 17:48:35 -0700102 }
103
104 /// Set the extension of a binder interface. This allows a downstream
105 /// developer to add an extension to an interface without modifying its
106 /// interface file. This should be called immediately when the object is
107 /// created before it is passed to another thread.
108 ///
109 /// # Examples
110 ///
111 /// For instance, imagine if we have this Binder AIDL interface definition:
112 /// interface IFoo { void doFoo(); }
113 ///
114 /// If an unrelated owner (perhaps in a downstream codebase) wants to make a
115 /// change to the interface, they have two options:
116 ///
117 /// 1) Historical option that has proven to be BAD! Only the original
118 /// author of an interface should change an interface. If someone
119 /// downstream wants additional functionality, they should not ever
120 /// change the interface or use this method.
121 /// ```AIDL
122 /// BAD TO DO: interface IFoo { BAD TO DO
123 /// BAD TO DO: void doFoo(); BAD TO DO
124 /// BAD TO DO: + void doBar(); // adding a method BAD TO DO
125 /// BAD TO DO: } BAD TO DO
126 /// ```
127 ///
128 /// 2) Option that this method enables!
129 /// Leave the original interface unchanged (do not change IFoo!).
130 /// Instead, create a new AIDL interface in a downstream package:
131 /// ```AIDL
132 /// package com.<name>; // new functionality in a new package
133 /// interface IBar { void doBar(); }
134 /// ```
135 ///
136 /// When registering the interface, add:
137 ///
138 /// # use binder::{Binder, Interface};
139 /// # type MyFoo = ();
140 /// # type MyBar = ();
141 /// # let my_foo = ();
142 /// # let my_bar = ();
143 /// let mut foo: Binder<MyFoo> = Binder::new(my_foo); // class in AOSP codebase
144 /// let bar: Binder<MyBar> = Binder::new(my_bar); // custom extension class
145 /// foo.set_extension(&mut bar.as_binder()); // use method in Binder
146 ///
147 /// Then, clients of `IFoo` can get this extension:
148 ///
149 /// # use binder::{declare_binder_interface, Binder, TransactionCode, Parcel};
150 /// # trait IBar {}
151 /// # declare_binder_interface! {
152 /// # IBar["test"] {
153 /// # native: BnBar(on_transact),
154 /// # proxy: BpBar,
155 /// # }
156 /// # }
157 /// # fn on_transact(
158 /// # service: &dyn IBar,
159 /// # code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000160 /// # data: &BorrowedParcel,
161 /// # reply: &mut BorrowedParcel,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700162 /// # ) -> binder::Result<()> {
163 /// # Ok(())
164 /// # }
165 /// # impl IBar for BpBar {}
166 /// # impl IBar for Binder<BnBar> {}
167 /// # fn main() -> binder::Result<()> {
168 /// # let binder = Binder::new(());
169 /// if let Some(barBinder) = binder.get_extension()? {
170 /// let bar = BpBar::new(barBinder)
171 /// .expect("Extension was not of type IBar");
172 /// } else {
173 /// // There was no extension
174 /// }
175 /// # }
176 pub fn set_extension(&mut self, extension: &mut SpIBinder) -> Result<()> {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100177 let status =
178 // Safety: `AIBinder_setExtension` expects two valid, mutable
179 // `AIBinder` pointers. We are guaranteed that both `self` and
180 // `extension` contain valid `AIBinder` pointers, because they
181 // cannot be initialized without a valid
182 // pointer. `AIBinder_setExtension` does not take ownership of
183 // either parameter.
184 unsafe { sys::AIBinder_setExtension(self.as_native_mut(), extension.as_native_mut()) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700185 status_result(status)
186 }
187
188 /// Retrieve the interface descriptor string for this object's Binder
189 /// interface.
190 pub fn get_descriptor() -> &'static str {
191 T::get_descriptor()
192 }
Stephen Craneff7f03a2021-02-25 16:04:22 -0800193
194 /// Mark this binder object with the given stability guarantee
195 fn mark_stability(&mut self, stability: Stability) {
196 match stability {
197 Stability::Local => self.mark_local_stability(),
198 Stability::Vintf => {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100199 // Safety: Self always contains a valid `AIBinder` pointer, so
200 // we can always call this C API safely.
Stephen Craneff7f03a2021-02-25 16:04:22 -0800201 unsafe {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800202 sys::AIBinder_markVintfStability(self.as_native_mut());
203 }
204 }
205 }
206 }
207
208 /// Mark this binder object with local stability, which is vendor if we are
Devin Moore3d5ca6b2023-02-17 02:10:50 +0000209 /// building for android_vendor and system otherwise.
210 #[cfg(android_vendor)]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800211 fn mark_local_stability(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100212 // Safety: Self always contains a valid `AIBinder` pointer, so we can
213 // always call this C API safely.
Stephen Craneff7f03a2021-02-25 16:04:22 -0800214 unsafe {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800215 sys::AIBinder_markVendorStability(self.as_native_mut());
216 }
217 }
218
219 /// Mark this binder object with local stability, which is vendor if we are
Devin Moore3d5ca6b2023-02-17 02:10:50 +0000220 /// building for android_vendor and system otherwise.
221 #[cfg(not(android_vendor))]
Stephen Craneff7f03a2021-02-25 16:04:22 -0800222 fn mark_local_stability(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100223 // Safety: Self always contains a valid `AIBinder` pointer, so we can
224 // always call this C API safely.
Stephen Craneff7f03a2021-02-25 16:04:22 -0800225 unsafe {
Stephen Craneff7f03a2021-02-25 16:04:22 -0800226 sys::AIBinder_markSystemStability(self.as_native_mut());
227 }
228 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700229}
230
231impl<T: Remotable> Interface for Binder<T> {
232 /// Converts the local remotable object into a generic `SpIBinder`
233 /// reference.
234 ///
235 /// The resulting `SpIBinder` will hold its own strong reference to this
236 /// remotable object, which will prevent the object from being dropped while
237 /// the `SpIBinder` is alive.
238 fn as_binder(&self) -> SpIBinder {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100239 // Safety: `self.ibinder` is guaranteed to always be a valid pointer
240 // to an `AIBinder` by the `Binder` constructor. We are creating a
241 // copy of the `self.ibinder` strong reference, but
242 // `SpIBinder::from_raw` assumes it receives an owned pointer with
243 // its own strong reference. We first increment the reference count,
244 // so that the new `SpIBinder` will be tracked as a new reference.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700245 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700246 sys::AIBinder_incStrong(self.ibinder);
247 SpIBinder::from_raw(self.ibinder).unwrap()
248 }
249 }
250}
251
252impl<T: Remotable> InterfaceClassMethods for Binder<T> {
253 fn get_descriptor() -> &'static str {
254 <T as Remotable>::get_descriptor()
255 }
256
257 /// Called whenever a transaction needs to be processed by a local
258 /// implementation.
259 ///
260 /// # Safety
261 ///
262 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
263 /// contains a `T` pointer in its user data. The `data` and `reply` parcel
264 /// parameters must be valid pointers to `AParcel` objects. This method does
265 /// not take ownership of any of its parameters.
266 ///
267 /// These conditions hold when invoked by `ABBinder::onTransact`.
268 unsafe extern "C" fn on_transact(
269 binder: *mut sys::AIBinder,
270 code: u32,
271 data: *const sys::AParcel,
272 reply: *mut sys::AParcel,
273 ) -> status_t {
274 let res = {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100275 // Safety: The caller must give us a parcel pointer which is either
276 // null or valid at least for the duration of this function call. We
277 // don't keep the resulting value beyond the function.
278 let mut reply = unsafe { BorrowedParcel::from_raw(reply).unwrap() };
279 // Safety: The caller must give us a parcel pointer which is either
280 // null or valid at least for the duration of this function call. We
281 // don't keep the resulting value beyond the function.
282 let data = unsafe { BorrowedParcel::from_raw(data as *mut sys::AParcel).unwrap() };
283 // Safety: Our caller promised that `binder` is a non-null, valid
284 // pointer to a local `AIBinder`.
285 let object = unsafe { sys::AIBinder_getUserData(binder) };
286 // Safety: Our caller promised that the binder has a `T` pointer in
287 // its user data.
288 let binder: &T = unsafe { &*(object as *const T) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700289 binder.on_transact(code, &data, &mut reply)
290 };
291 match res {
292 Ok(()) => 0i32,
293 Err(e) => e as i32,
294 }
295 }
296
297 /// Called whenever an `AIBinder` object is no longer referenced and needs
298 /// destroyed.
299 ///
300 /// # Safety
301 ///
302 /// Must be called with a valid pointer to a `T` object. After this call,
303 /// the pointer will be invalid and should not be dereferenced.
304 unsafe extern "C" fn on_destroy(object: *mut c_void) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100305 // Safety: Our caller promised that `object` is a valid pointer to a
306 // `T`.
307 drop(unsafe { Box::from_raw(object as *mut T) });
Stephen Crane2a3c2502020-06-16 17:48:35 -0700308 }
309
310 /// Called whenever a new, local `AIBinder` object is needed of a specific
311 /// class.
312 ///
313 /// Constructs the user data pointer that will be stored in the object,
314 /// which will be a heap-allocated `T` object.
315 ///
316 /// # Safety
317 ///
318 /// Must be called with a valid pointer to a `T` object allocated via `Box`.
319 unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void {
320 // We just return the argument, as it is already a pointer to the rust
321 // object created by Box.
322 args
323 }
Stephen Crane2a3297f2021-06-11 16:48:10 -0700324
325 /// Called to handle the `dump` transaction.
326 ///
327 /// # Safety
328 ///
329 /// Must be called with a non-null, valid pointer to a local `AIBinder` that
330 /// contains a `T` pointer in its user data. fd should be a non-owned file
331 /// descriptor, and args must be an array of null-terminated string
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100332 /// pointers with length num_args.
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100333 unsafe extern "C" fn on_dump(
334 binder: *mut sys::AIBinder,
335 fd: i32,
336 args: *mut *const c_char,
337 num_args: u32,
338 ) -> status_t {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700339 if fd < 0 {
340 return StatusCode::UNEXPECTED_NULL as status_t;
341 }
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.
344 let file = unsafe { ManuallyDrop::new(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 {
356 slice::from_raw_parts(args, num_args as usize)
357 .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) };
Stephen Crane2a3297f2021-06-11 16:48:10 -0700369 let res = binder.on_dump(&file, &args);
370
371 match res {
372 Ok(()) => 0,
373 Err(e) => e as status_t,
374 }
375 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700376}
377
378impl<T: Remotable> Drop for Binder<T> {
379 // This causes C++ to decrease the strong ref count of the `AIBinder`
380 // object. We specifically do not drop the `rust_object` here. When C++
381 // actually destroys the object, it calls `on_destroy` and we can drop the
382 // `rust_object` then.
383 fn drop(&mut self) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100384 // Safety: When `self` is dropped, we can no longer access the
385 // reference, so can decrement the reference count. `self.ibinder` is
386 // always a valid `AIBinder` pointer, so is valid to pass to
387 // `AIBinder_decStrong`.
Stephen Crane2a3c2502020-06-16 17:48:35 -0700388 unsafe {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700389 sys::AIBinder_decStrong(self.ibinder);
390 }
391 }
392}
393
394impl<T: Remotable> Deref for Binder<T> {
395 type Target = T;
396
397 fn deref(&self) -> &Self::Target {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100398 // Safety: While `self` is alive, the reference count of the underlying
399 // object is > 0 and therefore `on_destroy` cannot be called. Therefore
400 // while `self` is alive, we know that `rust_object` is still a valid
401 // pointer to a heap allocated object of type `T`.
402 unsafe { &*self.rust_object }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700403 }
404}
405
406impl<B: Remotable> Serialize for Binder<B> {
Alice Ryhl8618c482021-11-09 15:35:35 +0000407 fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700408 parcel.write_binder(Some(&self.as_binder()))
409 }
410}
411
412// This implementation is an idiomatic implementation of the C++
413// `IBinder::localBinder` interface if the binder object is a Rust binder
414// service.
415impl<B: Remotable> TryFrom<SpIBinder> for Binder<B> {
416 type Error = StatusCode;
417
418 fn try_from(mut ibinder: SpIBinder) -> Result<Self> {
419 let class = B::get_class();
420 if Some(class) != ibinder.get_class() {
421 return Err(StatusCode::BAD_TYPE);
422 }
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100423 // Safety: `SpIBinder` always holds a valid pointer pointer to an
424 // `AIBinder`, which we can safely pass to `AIBinder_getUserData`.
425 // `ibinder` retains ownership of the returned pointer.
426 let userdata = unsafe { sys::AIBinder_getUserData(ibinder.as_native_mut()) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700427 if userdata.is_null() {
428 return Err(StatusCode::UNEXPECTED_NULL);
429 }
430 // We are transferring the ownership of the AIBinder into the new Binder
431 // object.
432 let mut ibinder = ManuallyDrop::new(ibinder);
Matthew Maurere268a9f2022-07-26 09:31:30 -0700433 Ok(Binder { ibinder: ibinder.as_native_mut(), rust_object: userdata as *mut B })
Stephen Crane2a3c2502020-06-16 17:48:35 -0700434 }
435}
436
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100437/// Safety: The constructor for `Binder` guarantees that `self.ibinder` will
438/// contain a valid, non-null pointer to an `AIBinder`, so this implementation
439/// is type safe. `self.ibinder` will remain valid for the entire lifetime of
440/// `self` because we hold a strong reference to the `AIBinder` until `self` is
Stephen Crane2a3c2502020-06-16 17:48:35 -0700441/// dropped.
442unsafe impl<B: Remotable> AsNative<sys::AIBinder> for Binder<B> {
443 fn as_native(&self) -> *const sys::AIBinder {
444 self.ibinder
445 }
446
447 fn as_native_mut(&mut self) -> *mut sys::AIBinder {
448 self.ibinder
449 }
450}
451
452/// Register a new service with the default service manager.
453///
454/// Registers the given binder object with the given identifier. If successful,
455/// this service can then be retrieved using that identifier.
Alan Stokes1a49e4f2021-09-23 10:30:47 +0100456///
457/// This function will panic if the identifier contains a 0 byte (NUL).
Stephen Crane2a3c2502020-06-16 17:48:35 -0700458pub fn add_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
459 let instance = CString::new(identifier).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100460 let status =
461 // Safety: `AServiceManager_addService` expects valid `AIBinder` and C
462 // string pointers. Caller retains ownership of both pointers.
463 // `AServiceManager_addService` creates a new strong reference and copies
464 // the string, so both pointers need only be valid until the call returns.
465 unsafe { sys::AServiceManager_addService(binder.as_native_mut(), instance.as_ptr()) };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700466 status_result(status)
467}
468
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100469/// Register a dynamic service via the LazyServiceRegistrar.
470///
471/// Registers the given binder object with the given identifier. If successful,
472/// this service can then be retrieved using that identifier. The service process
473/// will be shut down once all registered services are no longer in use.
474///
475/// If any service in the process is registered as lazy, all should be, otherwise
476/// the process may be shut down while a service is in use.
Alan Stokes1a49e4f2021-09-23 10:30:47 +0100477///
478/// This function will panic if the identifier contains a 0 byte (NUL).
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100479pub fn register_lazy_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
480 let instance = CString::new(identifier).unwrap();
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100481 // Safety: `AServiceManager_registerLazyService` expects valid `AIBinder` and C
482 // string pointers. Caller retains ownership of both
483 // pointers. `AServiceManager_registerLazyService` creates a new strong reference
484 // and copies the string, so both pointers need only be valid until the
485 // call returns.
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100486 let status = unsafe {
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100487 sys::AServiceManager_registerLazyService(binder.as_native_mut(), instance.as_ptr())
488 };
489 status_result(status)
490}
491
492/// Prevent a process which registers lazy services from being shut down even when none
493/// of the services is in use.
494///
495/// If persist is true then shut down will be blocked until this function is called again with
496/// persist false. If this is to be the initial state, call this function before calling
497/// register_lazy_service.
Andrew Walbran7b0be1f2022-08-04 16:47:46 +0000498///
499/// Consider using [`LazyServiceGuard`] rather than calling this directly.
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100500pub fn force_lazy_services_persist(persist: bool) {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100501 // Safety: No borrowing or transfer of ownership occurs here.
502 unsafe { sys::AServiceManager_forceLazyServicesPersist(persist) }
Alan Stokes23fdfcd2021-09-09 11:19:24 +0100503}
504
Andrew Walbran7b0be1f2022-08-04 16:47:46 +0000505/// An RAII object to ensure a process which registers lazy services is not killed. During the
506/// lifetime of any of these objects the service manager will not not kill the process even if none
507/// of its lazy services are in use.
508#[must_use]
509#[derive(Debug)]
510pub struct LazyServiceGuard {
511 // Prevent construction outside this module.
512 _private: (),
513}
514
Andrew Walbran3a957462022-08-24 10:55:16 +0000515// Count of how many LazyServiceGuard objects are in existence.
516static GUARD_COUNT: Mutex<u64> = Mutex::new(0);
Andrew Walbran7b0be1f2022-08-04 16:47:46 +0000517
518impl LazyServiceGuard {
519 /// Create a new LazyServiceGuard to prevent the service manager prematurely killing this
520 /// process.
521 pub fn new() -> Self {
522 let mut count = GUARD_COUNT.lock().unwrap();
523 *count += 1;
524 if *count == 1 {
525 // It's important that we make this call with the mutex held, to make sure
526 // that multiple calls (e.g. if the count goes 1 -> 0 -> 1) are correctly
527 // sequenced. (That also means we can't just use an AtomicU64.)
528 force_lazy_services_persist(true);
529 }
530 Self { _private: () }
531 }
532}
533
534impl Drop for LazyServiceGuard {
535 fn drop(&mut self) {
536 let mut count = GUARD_COUNT.lock().unwrap();
537 *count -= 1;
538 if *count == 0 {
539 force_lazy_services_persist(false);
540 }
541 }
542}
543
544impl Clone for LazyServiceGuard {
545 fn clone(&self) -> Self {
546 Self::new()
547 }
548}
549
550impl Default for LazyServiceGuard {
551 fn default() -> Self {
552 Self::new()
553 }
554}
555
Stephen Crane2a3c2502020-06-16 17:48:35 -0700556/// Tests often create a base BBinder instance; so allowing the unit
557/// type to be remotable translates nicely to Binder::new(()).
558impl Remotable for () {
559 fn get_descriptor() -> &'static str {
560 ""
561 }
562
563 fn on_transact(
564 &self,
565 _code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000566 _data: &BorrowedParcel<'_>,
567 _reply: &mut BorrowedParcel<'_>,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700568 ) -> Result<()> {
569 Ok(())
570 }
571
Stephen Crane2a3297f2021-06-11 16:48:10 -0700572 fn on_dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
573 Ok(())
574 }
575
Stephen Crane2a3c2502020-06-16 17:48:35 -0700576 binder_fn_get_class!(Binder::<Self>);
577}
578
579impl Interface for () {}
Alice Ryhlad9c77b2021-11-16 09:49:29 +0000580
581/// Determine whether the current thread is currently executing an incoming
582/// transaction.
583pub fn is_handling_transaction() -> bool {
Andrew Walbran2f3ff9f2023-07-07 16:58:13 +0100584 // Safety: This method is always safe to call.
585 unsafe { sys::AIBinder_isHandlingTransaction() }
Alice Ryhlad9c77b2021-11-16 09:49:29 +0000586}