Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e78cc387 authored by Andrew Walbran's avatar Andrew Walbran Committed by Automerger Merge Worker
Browse files

Merge "Add more ergonomic API for persisting lazy services." am: b6405c79...

Merge "Add more ergonomic API for persisting lazy services." am: b6405c79 am: 6c2bc861 am: 8bf3b14f

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2177902



Change-Id: Ibc12b8ef102cbbdbcff592d139d836619c7491c3
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents bc3d4de0 8bf3b14f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -15,9 +15,10 @@ rust_library {
        "libutils",
    ],
    rustlibs: [
        "liblibc",
        "libbinder_ndk_sys",
        "libdowncast_rs",
        "liblazy_static",
        "liblibc",
    ],
    host_supported: true,
    vendor_available: true,
@@ -171,9 +172,10 @@ rust_test {
        "libbinder_ndk",
    ],
    rustlibs: [
        "liblibc",
        "libbinder_ndk_sys",
        "libdowncast_rs",
        "liblazy_static",
        "liblibc",
    ],
}

+1 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak};
pub use error::{ExceptionCode, Status, StatusCode};
pub use native::{
    add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service,
    LazyServiceGuard,
};
pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder};
pub use proxy::{
+57 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ use crate::parcel::{BorrowedParcel, Serialize};
use crate::proxy::SpIBinder;
use crate::sys;

use lazy_static::lazy_static;
use std::convert::TryFrom;
use std::ffi::{c_void, CStr, CString};
use std::fs::File;
@@ -30,6 +31,7 @@ use std::ops::Deref;
use std::os::raw::c_char;
use std::os::unix::io::FromRawFd;
use std::slice;
use std::sync::Mutex;

/// Rust wrapper around Binder remotable objects.
///
@@ -487,6 +489,8 @@ pub fn register_lazy_service(identifier: &str, mut binder: SpIBinder) -> Result<
/// 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.
///
/// Consider using [`LazyServiceGuard`] rather than calling this directly.
pub fn force_lazy_services_persist(persist: bool) {
    unsafe {
        // Safety: No borrowing or transfer of ownership occurs here.
@@ -494,6 +498,59 @@ pub fn force_lazy_services_persist(persist: bool) {
    }
}

/// An RAII object to ensure a process which registers lazy services is not killed. During the
/// lifetime of any of these objects the service manager will not not kill the process even if none
/// of its lazy services are in use.
#[must_use]
#[derive(Debug)]
pub struct LazyServiceGuard {
    // Prevent construction outside this module.
    _private: (),
}

lazy_static! {
    // Count of how many LazyServiceGuard objects are in existence.
    static ref GUARD_COUNT: Mutex<u64> = Mutex::new(0);
}

impl LazyServiceGuard {
    /// Create a new LazyServiceGuard to prevent the service manager prematurely killing this
    /// process.
    pub fn new() -> Self {
        let mut count = GUARD_COUNT.lock().unwrap();
        *count += 1;
        if *count == 1 {
            // It's important that we make this call with the mutex held, to make sure
            // that multiple calls (e.g. if the count goes 1 -> 0 -> 1) are correctly
            // sequenced. (That also means we can't just use an AtomicU64.)
            force_lazy_services_persist(true);
        }
        Self { _private: () }
    }
}

impl Drop for LazyServiceGuard {
    fn drop(&mut self) {
        let mut count = GUARD_COUNT.lock().unwrap();
        *count -= 1;
        if *count == 0 {
            force_lazy_services_persist(false);
        }
    }
}

impl Clone for LazyServiceGuard {
    fn clone(&self) -> Self {
        Self::new()
    }
}

impl Default for LazyServiceGuard {
    fn default() -> Self {
        Self::new()
    }
}

/// Tests often create a base BBinder instance; so allowing the unit
/// type to be remotable translates nicely to Binder::new(()).
impl Remotable for () {