Merge "Allow AVF C++ demo to use libbinder_rpc"
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 4472db1..98a70ed 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -301,7 +301,7 @@
}
if (!out && startIfNotFound) {
- tryStartService(name);
+ tryStartService(ctx, name);
}
if (out) {
@@ -651,10 +651,11 @@
}
}
-void ServiceManager::tryStartService(const std::string& name) {
- ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service. (if it's not "
- "configured to be a lazy service, it may be stuck starting or still starting).",
- name.c_str());
+void ServiceManager::tryStartService(const Access::CallingContext& ctx, const std::string& name) {
+ ALOGI("Since '%s' could not be found (requested by debug pid %d), trying to start it as a lazy "
+ "AIDL service. (if it's not configured to be a lazy service, it may be stuck starting or "
+ "still starting).",
+ name.c_str(), ctx.debugPid);
std::thread([=] {
if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 3aa6731..3b925a4 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -67,7 +67,7 @@
void clear();
protected:
- virtual void tryStartService(const std::string& name);
+ virtual void tryStartService(const Access::CallingContext& ctx, const std::string& name);
private:
struct Service {
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index 0fd8d8e..9e5b8a4 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -27,11 +27,14 @@
#include "Access.h"
#include "ServiceManager.h"
-using android::sp;
using android::Access;
using android::BBinder;
using android::IBinder;
using android::ServiceManager;
+using android::sp;
+using android::base::EndsWith;
+using android::base::GetProperty;
+using android::base::StartsWith;
using android::binder::Status;
using android::os::BnServiceCallback;
using android::os::IServiceManager;
@@ -62,7 +65,7 @@
class MockServiceManager : public ServiceManager {
public:
MockServiceManager(std::unique_ptr<Access>&& access) : ServiceManager(std::move(access)) {}
- MOCK_METHOD1(tryStartService, void(const std::string& name));
+ MOCK_METHOD2(tryStartService, void(const Access::CallingContext&, const std::string& name));
};
static sp<ServiceManager> getPermissiveServiceManager() {
@@ -77,9 +80,11 @@
return sm;
}
-static bool isCuttlefish() {
- return android::base::StartsWith(android::base::GetProperty("ro.product.vendor.device", ""),
- "vsoc_");
+// Determines if test device is a cuttlefish phone device
+static bool isCuttlefishPhone() {
+ auto device = GetProperty("ro.product.vendor.device", "");
+ auto product = GetProperty("ro.product.vendor.name", "");
+ return StartsWith(device, "vsoc_") && EndsWith(product, "_phone");
}
TEST(AddService, HappyHappy) {
@@ -314,7 +319,7 @@
}
TEST(Vintf, UpdatableViaApex) {
- if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+ if (!isCuttlefishPhone()) GTEST_SKIP() << "Skipping non-Cuttlefish-phone devices";
auto sm = getPermissiveServiceManager();
std::optional<std::string> updatableViaApex;
@@ -326,7 +331,7 @@
}
TEST(Vintf, UpdatableViaApex_InvalidNameReturnsNullOpt) {
- if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+ if (!isCuttlefishPhone()) GTEST_SKIP() << "Skipping non-Cuttlefish-phone devices";
auto sm = getPermissiveServiceManager();
std::optional<std::string> updatableViaApex;
@@ -337,7 +342,7 @@
}
TEST(Vintf, GetUpdatableNames) {
- if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+ if (!isCuttlefishPhone()) GTEST_SKIP() << "Skipping non-Cuttlefish-phone devices";
auto sm = getPermissiveServiceManager();
std::vector<std::string> names;
@@ -348,7 +353,7 @@
}
TEST(Vintf, GetUpdatableNames_InvalidApexNameReturnsEmpty) {
- if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+ if (!isCuttlefishPhone()) GTEST_SKIP() << "Skipping non-Cuttlefish-phone devices";
auto sm = getPermissiveServiceManager();
std::vector<std::string> names;
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index d0e35de..b90b40b 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -1122,6 +1122,10 @@
}
impl $crate::binder_impl::Deserialize for $enum {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType { Self::UninitType::default() }
+ fn from_init(value: Self) -> Self::UninitType { value }
+
fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
parcel.read().map(Self)
}
diff --git a/libs/binder/rust/src/error.rs b/libs/binder/rust/src/error.rs
index f6b09ed..ba26062 100644
--- a/libs/binder/rust/src/error.rs
+++ b/libs/binder/rust/src/error.rs
@@ -20,6 +20,7 @@
use std::error;
use std::ffi::{CStr, CString};
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
+use std::ptr;
use std::result;
pub use sys::binder_status_t as status_t;
@@ -92,7 +93,7 @@
/// track of and chain binder errors along with service specific errors.
///
/// Used in AIDL transactions to represent failed transactions.
-pub struct Status(*mut sys::AStatus);
+pub struct Status(ptr::NonNull<sys::AStatus>);
// Safety: The `AStatus` that the `Status` points to must have an entirely thread-safe API for the
// duration of the `Status` object's lifetime. We ensure this by not allowing mutation of a `Status`
@@ -119,7 +120,7 @@
// Rust takes ownership of the returned pointer.
sys::AStatus_newOk()
};
- Self(ptr)
+ Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
}
/// Create a status object from a service specific error
@@ -147,7 +148,7 @@
sys::AStatus_fromServiceSpecificError(err)
}
};
- Self(ptr)
+ Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
}
/// Creates a status object from a service specific error.
@@ -161,7 +162,7 @@
let ptr = unsafe {
sys::AStatus_fromExceptionCodeWithMessage(exception as i32, message.as_ptr())
};
- Self(ptr)
+ Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
} else {
exception.into()
}
@@ -181,7 +182,7 @@
///
/// This constructor is safe iff `ptr` is a valid pointer to an `AStatus`.
pub(crate) unsafe fn from_ptr(ptr: *mut sys::AStatus) -> Self {
- Self(ptr)
+ Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
}
/// Returns `true` if this status represents a successful transaction.
@@ -326,7 +327,7 @@
// UNKNOWN_ERROR.
sys::AStatus_fromStatus(status)
};
- Self(ptr)
+ Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
}
}
@@ -338,7 +339,7 @@
// Unknown values will be coerced into EX_TRANSACTION_FAILED.
sys::AStatus_fromExceptionCode(code as i32)
};
- Self(ptr)
+ Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
}
}
@@ -367,7 +368,7 @@
// pointee, so we need to delete it here. We know that the pointer
// will be valid here since `Status` always contains a valid pointer
// while it is alive.
- sys::AStatus_delete(self.0);
+ sys::AStatus_delete(self.0.as_mut());
}
}
}
@@ -381,11 +382,15 @@
/// `Status` object is still alive.
unsafe impl AsNative<sys::AStatus> for Status {
fn as_native(&self) -> *const sys::AStatus {
- self.0
+ self.0.as_ptr()
}
fn as_native_mut(&mut self) -> *mut sys::AStatus {
- self.0
+ unsafe {
+ // Safety: The pointer will be valid here since `Status` always
+ // contains a valid and initialized pointer while it is alive.
+ self.0.as_mut()
+ }
}
}
diff --git a/libs/binder/rust/src/parcel/file_descriptor.rs b/libs/binder/rust/src/parcel/file_descriptor.rs
index de6d649..7fe37f3 100644
--- a/libs/binder/rust/src/parcel/file_descriptor.rs
+++ b/libs/binder/rust/src/parcel/file_descriptor.rs
@@ -132,6 +132,14 @@
}
impl Deserialize for ParcelFileDescriptor {
+ type UninitType = Option<Self>;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ Some(value)
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel).transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
}
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index 4b658fc..5d8c11c 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-use crate::binder::{AsNative, FromIBinder, Stability, Strong};
+use crate::binder::{AsNative, FromIBinder, Interface, Stability, Strong};
use crate::error::{status_result, status_t, Result, Status, StatusCode};
use crate::parcel::BorrowedParcel;
use crate::proxy::SpIBinder;
@@ -22,7 +22,7 @@
use std::convert::{TryFrom, TryInto};
use std::ffi::c_void;
-use std::mem::{self, ManuallyDrop, MaybeUninit};
+use std::mem::{self, ManuallyDrop};
use std::os::raw::c_char;
use std::ptr;
use std::slice;
@@ -60,6 +60,26 @@
/// A struct whose instances can be restored from a [`Parcel`].
// Might be able to hook this up as a serde backend in the future?
pub trait Deserialize: Sized {
+ /// Type for the uninitialized value of this type. Will be either `Self`
+ /// if the type implements `Default`, `Option<Self>` otherwise.
+ type UninitType;
+
+ /// Assert at compile-time that `Self` and `Self::UninitType` have the same
+ /// size and alignment. This will either fail to compile or evaluate to `true`.
+ /// The only two macros that work here are `panic!` and `assert!`, so we cannot
+ /// use `assert_eq!`.
+ const ASSERT_UNINIT_SIZE_AND_ALIGNMENT: bool = {
+ assert!(std::mem::size_of::<Self>() == std::mem::size_of::<Self::UninitType>());
+ assert!(std::mem::align_of::<Self>() == std::mem::align_of::<Self::UninitType>());
+ true
+ };
+
+ /// Return an uninitialized or default-initialized value for this type.
+ fn uninit() -> Self::UninitType;
+
+ /// Convert an initialized value of type `Self` into `Self::UninitType`.
+ fn from_init(value: Self) -> Self::UninitType;
+
/// Deserialize an instance from the given [`Parcel`].
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self>;
@@ -121,7 +141,7 @@
pub trait DeserializeArray: Deserialize {
/// Deserialize an array of type from the given parcel.
fn deserialize_array(parcel: &BorrowedParcel<'_>) -> Result<Option<Vec<Self>>> {
- let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
+ let mut vec: Option<Vec<Self::UninitType>> = None;
let res = unsafe {
// Safety: Safe FFI, vec is the correct opaque type expected by
// allocate_vec and deserialize_element.
@@ -136,8 +156,8 @@
let vec: Option<Vec<Self>> = unsafe {
// Safety: We are assuming that the NDK correctly initialized every
// element of the vector by now, so we know that all the
- // MaybeUninits are now properly initialized. We can transmute from
- // Vec<MaybeUninit<T>> to Vec<T> because MaybeUninit<T> has the same
+ // UninitTypes are now properly initialized. We can transmute from
+ // Vec<T::UninitType> to Vec<T> because T::UninitType has the same
// alignment and size as T, so the pointer to the vector allocation
// will be compatible.
mem::transmute(vec)
@@ -149,14 +169,14 @@
/// Callback to deserialize a parcelable element.
///
/// The opaque array data pointer must be a mutable pointer to an
-/// `Option<Vec<MaybeUninit<T>>>` with at least enough elements for `index` to be valid
+/// `Option<Vec<T::UninitType>>` with at least enough elements for `index` to be valid
/// (zero-based).
unsafe extern "C" fn deserialize_element<T: Deserialize>(
parcel: *const sys::AParcel,
array: *mut c_void,
index: usize,
) -> status_t {
- let vec = &mut *(array as *mut Option<Vec<MaybeUninit<T>>>);
+ let vec = &mut *(array as *mut Option<Vec<T::UninitType>>);
let vec = match vec {
Some(v) => v,
None => return StatusCode::BAD_INDEX as status_t,
@@ -170,7 +190,7 @@
Ok(e) => e,
Err(code) => return code as status_t,
};
- ptr::write(vec[index].as_mut_ptr(), element);
+ vec[index] = T::from_init(element);
StatusCode::OK as status_t
}
@@ -233,15 +253,15 @@
/// # Safety
///
/// The opaque data pointer passed to the array read function must be a mutable
-/// pointer to an `Option<Vec<MaybeUninit<T>>>`. `buffer` will be assigned a mutable pointer
+/// pointer to an `Option<Vec<T::UninitType>>`. `buffer` will be assigned a mutable pointer
/// to the allocated vector data if this function returns true.
-unsafe extern "C" fn allocate_vec_with_buffer<T>(
+unsafe extern "C" fn allocate_vec_with_buffer<T: Deserialize>(
data: *mut c_void,
len: i32,
buffer: *mut *mut T,
) -> bool {
let res = allocate_vec::<T>(data, len);
- let vec = &mut *(data as *mut Option<Vec<MaybeUninit<T>>>);
+ let vec = &mut *(data as *mut Option<Vec<T::UninitType>>);
if let Some(new_vec) = vec {
*buffer = new_vec.as_mut_ptr() as *mut T;
}
@@ -253,20 +273,18 @@
/// # Safety
///
/// The opaque data pointer passed to the array read function must be a mutable
-/// pointer to an `Option<Vec<MaybeUninit<T>>>`.
-unsafe extern "C" fn allocate_vec<T>(data: *mut c_void, len: i32) -> bool {
- let vec = &mut *(data as *mut Option<Vec<MaybeUninit<T>>>);
+/// pointer to an `Option<Vec<T::UninitType>>`.
+unsafe extern "C" fn allocate_vec<T: Deserialize>(data: *mut c_void, len: i32) -> bool {
+ let vec = &mut *(data as *mut Option<Vec<T::UninitType>>);
if len < 0 {
*vec = None;
return true;
}
- let mut new_vec: Vec<MaybeUninit<T>> = Vec::with_capacity(len as usize);
- // Safety: We are filling the vector with uninitialized data here, but this
- // is safe because the vector contains MaybeUninit elements which can be
- // uninitialized. We're putting off the actual unsafe bit, transmuting the
- // vector to a Vec<T> until the contents are initialized.
- new_vec.set_len(len as usize);
+ // Assert at compile time that `T` and `T::UninitType` have the same size and alignment.
+ let _ = T::ASSERT_UNINIT_SIZE_AND_ALIGNMENT;
+ let mut new_vec: Vec<T::UninitType> = Vec::with_capacity(len as usize);
+ new_vec.resize_with(len as usize, T::uninit);
ptr::write(vec, Some(new_vec));
true
@@ -283,8 +301,11 @@
}
/// Safety: All elements in the vector must be properly initialized.
-unsafe fn vec_assume_init<T>(vec: Vec<MaybeUninit<T>>) -> Vec<T> {
- // We can convert from Vec<MaybeUninit<T>> to Vec<T> because MaybeUninit<T>
+unsafe fn vec_assume_init<T: Deserialize>(vec: Vec<T::UninitType>) -> Vec<T> {
+ // Assert at compile time that `T` and `T::UninitType` have the same size and alignment.
+ let _ = T::ASSERT_UNINIT_SIZE_AND_ALIGNMENT;
+
+ // We can convert from Vec<T::UninitType> to Vec<T> because T::UninitType
// has the same alignment and size as T, so the pointer to the vector
// allocation will be compatible.
let mut vec = ManuallyDrop::new(vec);
@@ -307,6 +328,9 @@
{Deserialize, $ty:ty, $read_fn:path} => {
impl Deserialize for $ty {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType { Self::UninitType::default() }
+ fn from_init(value: Self) -> Self::UninitType { value }
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let mut val = Self::default();
unsafe {
@@ -348,11 +372,11 @@
{DeserializeArray, $ty:ty, $read_array_fn:path} => {
impl DeserializeArray for $ty {
fn deserialize_array(parcel: &BorrowedParcel<'_>) -> Result<Option<Vec<Self>>> {
- let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
+ let mut vec: Option<Vec<Self::UninitType>> = None;
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
// `AParcel`. `allocate_vec<T>` expects the opaque pointer to
- // be of type `*mut Option<Vec<MaybeUninit<T>>>`, so `&mut vec` is
+ // be of type `*mut Option<Vec<T::UninitType>>`, so `&mut vec` is
// correct for it.
$read_array_fn(
parcel.as_native(),
@@ -364,7 +388,7 @@
let vec: Option<Vec<Self>> = unsafe {
// Safety: We are assuming that the NDK correctly
// initialized every element of the vector by now, so we
- // know that all the MaybeUninits are now properly
+ // know that all the UninitTypes are now properly
// initialized.
vec.map(|vec| vec_assume_init(vec))
};
@@ -440,6 +464,14 @@
}
impl Deserialize for u8 {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
i8::deserialize(parcel).map(|v| v as u8)
}
@@ -471,6 +503,14 @@
}
impl Deserialize for i16 {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
u16::deserialize(parcel).map(|v| v as i16)
}
@@ -547,6 +587,14 @@
}
impl Deserialize for Option<String> {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let mut vec: Option<Vec<u8>> = None;
let status = unsafe {
@@ -575,6 +623,14 @@
impl DeserializeArray for Option<String> {}
impl Deserialize for String {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel).transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
}
@@ -611,6 +667,14 @@
}
impl<T: DeserializeArray> Deserialize for Vec<T> {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
DeserializeArray::deserialize_array(parcel)
.transpose()
@@ -640,6 +704,14 @@
impl<T: SerializeArray, const N: usize> SerializeArray for [T; N] {}
impl<T: DeserializeArray, const N: usize> Deserialize for [T; N] {
+ type UninitType = [T::UninitType; N];
+ fn uninit() -> Self::UninitType {
+ [(); N].map(|_| T::uninit())
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value.map(T::from_init)
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let vec = DeserializeArray::deserialize_array(parcel)
.transpose()
@@ -664,6 +736,14 @@
}
impl Deserialize for Stability {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
i32::deserialize(parcel).and_then(Stability::try_from)
}
@@ -682,6 +762,14 @@
}
impl Deserialize for Status {
+ type UninitType = Option<Self>;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ Some(value)
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let mut status_ptr = ptr::null_mut();
let ret_status = unsafe {
@@ -717,12 +805,29 @@
impl<T: Serialize + FromIBinder + ?Sized> SerializeArray for Strong<T> {}
impl<T: FromIBinder + ?Sized> Deserialize for Strong<T> {
+ type UninitType = Option<Strong<T>>;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ Some(value)
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let ibinder: SpIBinder = parcel.read()?;
FromIBinder::try_from(ibinder)
}
}
+struct AssertIBinder;
+impl Interface for AssertIBinder {}
+impl FromIBinder for AssertIBinder {
+ // This is only needed so we can assert on the size of Strong<AssertIBinder>
+ fn try_from(_: SpIBinder) -> Result<Strong<Self>> {
+ unimplemented!()
+ }
+}
+
impl<T: FromIBinder + ?Sized> DeserializeOption for Strong<T> {
fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
let ibinder: Option<SpIBinder> = parcel.read()?;
@@ -752,6 +857,14 @@
}
impl<T: DeserializeOption> Deserialize for Option<T> {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
DeserializeOption::deserialize_option(parcel)
}
@@ -821,6 +934,9 @@
};
($parcelable:ident < $( $param:ident ),* > ) => {
impl < $($param: Default),* > $crate::binder_impl::Deserialize for $parcelable < $($param),* > {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType { Self::UninitType::default() }
+ fn from_init(value: Self) -> Self::UninitType { value }
fn deserialize(
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
) -> std::result::Result<Self, $crate::StatusCode> {
@@ -876,6 +992,14 @@
}
impl<T: Deserialize> Deserialize for Box<T> {
+ type UninitType = Option<Self>;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ Some(value)
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel).map(Box::new)
}
@@ -900,6 +1024,7 @@
#[test]
fn test_custom_parcelable() {
+ #[derive(Default)]
struct Custom(u32, bool, String, Vec<String>);
impl Serialize for Custom {
@@ -912,6 +1037,14 @@
}
impl Deserialize for Custom {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Ok(Custom(
parcel.read()?,
diff --git a/libs/binder/rust/src/parcel/parcelable_holder.rs b/libs/binder/rust/src/parcel/parcelable_holder.rs
index c829d37..383cc83 100644
--- a/libs/binder/rust/src/parcel/parcelable_holder.rs
+++ b/libs/binder/rust/src/parcel/parcelable_holder.rs
@@ -169,6 +169,14 @@
}
impl Deserialize for ParcelableHolder {
+ type UninitType = Self;
+ fn uninit() -> Self::UninitType {
+ Self::new(Default::default())
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ value
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self, StatusCode> {
let status: i32 = parcel.read()?;
if status == NULL_PARCELABLE_FLAG {
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 254efae..036f6b4 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -439,6 +439,14 @@
impl SerializeArray for SpIBinder {}
impl Deserialize for SpIBinder {
+ type UninitType = Option<Self>;
+ fn uninit() -> Self::UninitType {
+ Self::UninitType::default()
+ }
+ fn from_init(value: Self) -> Self::UninitType {
+ Some(value)
+ }
+
fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
parcel.read_binder().transpose().unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 0280c96..4929b34 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -792,3 +792,15 @@
hotlists: ["4637097"],
},
}
+
+cc_defaults {
+ name: "fuzzer_disable_leaks",
+ fuzz_config: {
+ asan_options: [
+ "detect_leaks=0",
+ ],
+ hwasan_options: [
+ "detect_leaks=0",
+ ],
+ },
+}
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 2ac1174..0fe6f24 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -214,6 +214,7 @@
shared_libs: [
"libbinder",
+ "libGLESv2",
],
export_shared_lib_headers: [
@@ -326,7 +327,6 @@
"libbase",
"libcutils",
"libEGL",
- "libGLESv2",
"libhidlbase",
"liblog",
"libnativewindow",
diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp
index 0d6e476..cb586c6 100644
--- a/services/sensorservice/aidl/fuzzer/Android.bp
+++ b/services/sensorservice/aidl/fuzzer/Android.bp
@@ -11,6 +11,7 @@
name: "libsensorserviceaidl_fuzzer",
defaults: [
"service_fuzzer_defaults",
+ "fuzzer_disable_leaks",
],
host_supported: true,
static_libs: [