Expose lazy services to Rust
Expose register_lazy_service to allow a dynamic service to be
registered. Also expose force_lazy_services_persist to allow a process
with lazy services to temporarily prevent itself being shut down.
Bug: 199367367
Test: Run compos_key_cmd to start a VM and exit; VS process is stopped.
Change-Id: Ie26d73ed2a5ed8a9eee04ee1f28c12a3cbea3f1c
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index a0dfeec..e7c3396 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-use crate::binder::{AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode};
+use crate::binder::{
+ AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode,
+};
use crate::error::{status_result, status_t, Result, StatusCode};
use crate::parcel::{Parcel, Serialize};
use crate::proxy::SpIBinder;
@@ -321,7 +323,12 @@
/// contains a `T` pointer in its user data. fd should be a non-owned file
/// descriptor, and args must be an array of null-terminated string
/// poiinters with length num_args.
- unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t {
+ unsafe extern "C" fn on_dump(
+ binder: *mut sys::AIBinder,
+ fd: i32,
+ args: *mut *const c_char,
+ num_args: u32,
+ ) -> status_t {
if fd < 0 {
return StatusCode::UNEXPECTED_NULL as status_t;
}
@@ -447,6 +454,41 @@
status_result(status)
}
+/// Register a dynamic service via the LazyServiceRegistrar.
+///
+/// Registers the given binder object with the given identifier. If successful,
+/// this service can then be retrieved using that identifier. The service process
+/// will be shut down once all registered services are no longer in use.
+///
+/// If any service in the process is registered as lazy, all should be, otherwise
+/// the process may be shut down while a service is in use.
+pub fn register_lazy_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
+ let instance = CString::new(identifier).unwrap();
+ let status = unsafe {
+ // Safety: `AServiceManager_registerLazyService` expects valid `AIBinder` and C
+ // string pointers. Caller retains ownership of both
+ // pointers. `AServiceManager_registerLazyService` creates a new strong reference
+ // and copies the string, so both pointers need only be valid until the
+ // call returns.
+
+ sys::AServiceManager_registerLazyService(binder.as_native_mut(), instance.as_ptr())
+ };
+ status_result(status)
+}
+
+/// Prevent a process which registers lazy services from being shut down even when none
+/// of the services is in use.
+///
+/// If persist is true then shut down will be blocked until this function is called again with
+/// persist false. If this is to be the initial state, call this function before calling
+/// register_lazy_service.
+pub fn force_lazy_services_persist(persist: bool) {
+ unsafe {
+ // Safety: No borrowing or transfer of ownership occurs here.
+ sys::AServiceManager_forceLazyServicesPersist(persist)
+ }
+}
+
/// Tests often create a base BBinder instance; so allowing the unit
/// type to be remotable translates nicely to Binder::new(()).
impl Remotable for () {