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

Commit cde5e163 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 am: e78cc387

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



Change-Id: Id536b14aae628d092d82b55765b0252795d38e42
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents dfb8bb84 e78cc387
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 () {