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

Commit 78128526 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8220313 from 757c9f21 to tm-d1-release

Change-Id: I9598778b2894c21d106b85d7dc614de4fa4da3b2
parents 8165f1e0 757c9f21
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -114,8 +114,8 @@ pub use native::{
};
pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder};
pub use proxy::{
    get_interface, get_service, wait_for_interface, wait_for_service, DeathRecipient, SpIBinder,
    WpIBinder,
    get_declared_instances, get_interface, get_service, is_declared, wait_for_interface,
    wait_for_service, DeathRecipient, SpIBinder, WpIBinder,
};
pub use state::{ProcessState, ThreadState};

+57 −1
Original line number Diff line number Diff line
@@ -28,9 +28,10 @@ use crate::sys;

use std::cmp::Ordering;
use std::convert::TryInto;
use std::ffi::{c_void, CString};
use std::ffi::{c_void, CStr, CString};
use std::fmt;
use std::mem;
use std::os::raw::c_char;
use std::os::unix::io::AsRawFd;
use std::ptr;
use std::sync::Arc;
@@ -778,6 +779,61 @@ pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<
    }
}

/// Check if a service is declared (e.g. in a VINTF manifest)
pub fn is_declared(interface: &str) -> Result<bool> {
    let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;

    unsafe {
        // Safety: `interface` is a valid null-terminated C-style string and is
        // only borrowed for the lifetime of the call. The `interface` local
        // outlives this call as it lives for the function scope.
        Ok(sys::AServiceManager_isDeclared(interface.as_ptr()))
    }
}

/// Retrieve all declared instances for a particular interface
///
/// For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo'
/// is passed here, then ["foo"] would be returned.
pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
    unsafe extern "C" fn callback(instance: *const c_char, opaque: *mut c_void) {
        // Safety: opaque was a mutable pointer created below from a Vec of
        // CString, and outlives this callback. The null handling here is just
        // to avoid the possibility of unwinding across C code if this crate is
        // ever compiled with panic=unwind.
        if let Some(instances) = opaque.cast::<Vec<CString>>().as_mut() {
            // Safety: instance is a valid null-terminated C string with a
            // lifetime at least as long as this function, and we immediately
            // copy it into an owned CString.
            instances.push(CStr::from_ptr(instance).to_owned());
        } else {
            eprintln!("Opaque pointer was null in get_declared_instances callback!");
        }
    }

    let interface = CString::new(interface).or(Err(StatusCode::UNEXPECTED_NULL))?;
    let mut instances: Vec<CString> = vec![];
    unsafe {
        // Safety: `interface` and `instances` are borrowed for the length of
        // this call and both outlive the call. `interface` is guaranteed to be
        // a valid null-terminated C-style string.
        sys::AServiceManager_forEachDeclaredInstance(
            interface.as_ptr(),
            &mut instances as *mut _ as *mut c_void,
            Some(callback),
        );
    }

    instances
        .into_iter()
        .map(CString::into_string)
        .collect::<std::result::Result<Vec<String>, _>>()
        .map_err(|e| {
            eprintln!("An interface instance name was not a valid UTF-8 string: {}", e);
            StatusCode::BAD_VALUE
        })
}

/// # Safety
///
/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
+15 −0
Original line number Diff line number Diff line
@@ -483,6 +483,21 @@ mod tests {
        );
    }

    #[test]
    fn get_declared_instances() {
        // At the time of writing this test, there is no good VINTF interface
        // guaranteed to be on all devices. Cuttlefish has light, so this will
        // generally test things.
        let has_lights = binder::is_declared("android.hardware.light.ILights/default")
            .expect("Could not check for declared interface");

        let instances = binder::get_declared_instances("android.hardware.light.ILights")
            .expect("Could not get declared instances");

        let expected_defaults = if has_lights { 1 } else { 0 };
        assert_eq!(expected_defaults, instances.iter().filter(|i| i.as_str() == "default").count());
    }

    #[test]
    fn trivial_client() {
        let service_name = "trivial_client_test";
+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public:
    virtual void applyChangedTypesToLayers(const ChangedTypes&);
    virtual void applyDisplayRequests(const DisplayRequests&);
    virtual void applyLayerRequestsToLayers(const LayerRequests&);
    virtual void applyClientTargetRequests(const ClientTargetProperty&, float whitePointNits);
    virtual void applyClientTargetRequests(const ClientTargetProperty&, float brightness);

    // Internal
    virtual void setConfiguration(const compositionengine::DisplayCreationArgs&);
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#pragma once

#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>

@@ -63,4 +64,13 @@ void dumpVal(std::string& out, const char* name, const ui::Transform&);
void dumpVal(std::string& out, const char* name, const mat4&);
void dumpVal(std::string& out, const char* name, const StretchEffect&);

template <typename T>
void dumpVal(std::string& out, const char* name, std::optional<T> value) {
    if (value.has_value()) {
        return dumpVal(out, name, *value);
    } else {
        return dumpVal(out, name, "nullopt");
    }
}

} // namespace android::compositionengine::impl
Loading