Merge "Revert "Exclude setting code maps from APEX"" into main
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 4b7af45..3711362 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -683,7 +683,7 @@
return err;
}
-int Parcel::compareData(const Parcel& other) {
+int Parcel::compareData(const Parcel& other) const {
size_t size = dataSize();
if (size != other.dataSize()) {
return size < other.dataSize() ? -1 : 1;
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 5cc0830..c394ac7 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -92,7 +92,7 @@
LIBBINDER_EXPORTED status_t appendFrom(const Parcel* parcel, size_t start, size_t len);
- LIBBINDER_EXPORTED int compareData(const Parcel& other);
+ LIBBINDER_EXPORTED int compareData(const Parcel& other) const;
LIBBINDER_EXPORTED status_t compareDataInRange(size_t thisOffset, const Parcel& other,
size_t otherOffset, size_t length,
int* result) const;
@@ -637,9 +637,6 @@
LIBBINDER_EXPORTED const flat_binder_object* readObject(bool nullMetaData) const;
- // Explicitly close all file descriptors in the parcel.
- LIBBINDER_EXPORTED void closeFileDescriptors();
-
// Debugging: get metrics on current allocations.
LIBBINDER_EXPORTED static size_t getGlobalAllocSize();
LIBBINDER_EXPORTED static size_t getGlobalAllocCount();
@@ -652,6 +649,9 @@
LIBBINDER_EXPORTED void print(std::ostream& to, uint32_t flags = 0) const;
private:
+ // Explicitly close all file descriptors in the parcel.
+ void closeFileDescriptors();
+
// `objects` and `objectsSize` always 0 for RPC Parcels.
typedef void (*release_func)(const uint8_t* data, size_t dataSize, const binder_size_t* objects,
size_t objectsSize);
diff --git a/libs/binder/ndk/binder_rpc.cpp b/libs/binder/ndk/binder_rpc.cpp
index 2cc5f81..3c32a39 100644
--- a/libs/binder/ndk/binder_rpc.cpp
+++ b/libs/binder/ndk/binder_rpc.cpp
@@ -94,7 +94,7 @@
}
void* mData;
ABinderRpc_AccessorProviderUserData_deleteCallback mOnDelete;
- // needs to be copyable for std::function, but we will never copy it
+ // needs to be copy-able for std::function, but we will never copy it
OnDeleteProviderHolder(const OnDeleteProviderHolder&) {
LOG_ALWAYS_FATAL("This object can't be copied!");
}
@@ -113,7 +113,7 @@
}
if (data && onDelete == nullptr) {
ALOGE("If a non-null data ptr is passed to ABinderRpc_registerAccessorProvider, then a "
- "ABinderRpc_AccessorProviderUserData_deleteCallback must alse be passed to delete "
+ "ABinderRpc_AccessorProviderUserData_deleteCallback must also be passed to delete "
"the data object once the ABinderRpc_AccessorProvider is removed.");
return nullptr;
}
@@ -179,7 +179,7 @@
}
void* mData;
ABinderRpc_ConnectionInfoProviderUserData_delete mOnDelete;
- // needs to be copyable for std::function, but we will never copy it
+ // needs to be copy-able for std::function, but we will never copy it
OnDeleteConnectionInfoHolder(const OnDeleteConnectionInfoHolder&) {
LOG_ALWAYS_FATAL("This object can't be copied!");
}
@@ -197,7 +197,7 @@
}
if (data && onDelete == nullptr) {
ALOGE("If a non-null data ptr is passed to ABinderRpc_Accessor_new, then a "
- "ABinderRpc_ConnectionInfoProviderUserData_delete callback must alse be passed to "
+ "ABinderRpc_ConnectionInfoProviderUserData_delete callback must also be passed to "
"delete "
"the data object once the ABinderRpc_Accessor is deleted.");
return nullptr;
@@ -304,7 +304,7 @@
ABinderRpc_ConnectionInfo* ABinderRpc_ConnectionInfo_new(const sockaddr* addr, socklen_t len) {
if (addr == nullptr || len < 0 || static_cast<size_t>(len) < sizeof(sa_family_t)) {
- ALOGE("Invalid arguments in Arpc_Connection_new");
+ ALOGE("Invalid arguments in ABinderRpc_Connection_new");
return nullptr;
}
// socklen_t was int32_t on 32-bit and uint32_t on 64 bit.
@@ -317,8 +317,9 @@
return nullptr;
}
sockaddr_vm vm = *reinterpret_cast<const sockaddr_vm*>(addr);
- LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_VSOCK. family %d, port %d, cid %d",
- vm.svm_family, vm.svm_port, vm.svm_cid);
+ LOG_ACCESSOR_DEBUG(
+ "ABinderRpc_ConnectionInfo_new found AF_VSOCK. family %d, port %d, cid %d",
+ vm.svm_family, vm.svm_port, vm.svm_cid);
return new ABinderRpc_ConnectionInfo(vm);
} else if (addr->sa_family == AF_UNIX) {
if (len != sizeof(sockaddr_un)) {
@@ -327,7 +328,7 @@
return nullptr;
}
sockaddr_un un = *reinterpret_cast<const sockaddr_un*>(addr);
- LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_UNIX. family %d, path %s",
+ LOG_ACCESSOR_DEBUG("ABinderRpc_ConnectionInfo_new found AF_UNIX. family %d, path %s",
un.sun_family, un.sun_path);
return new ABinderRpc_ConnectionInfo(un);
} else if (addr->sa_family == AF_INET) {
@@ -337,12 +338,14 @@
return nullptr;
}
sockaddr_in in = *reinterpret_cast<const sockaddr_in*>(addr);
- LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_INET. family %d, address %s, port %d",
- in.sin_family, inet_ntoa(in.sin_addr), ntohs(in.sin_port));
+ LOG_ACCESSOR_DEBUG(
+ "ABinderRpc_ConnectionInfo_new found AF_INET. family %d, address %s, port %d",
+ in.sin_family, inet_ntoa(in.sin_addr), ntohs(in.sin_port));
return new ABinderRpc_ConnectionInfo(in);
}
- ALOGE("ARpc APIs only support AF_VSOCK right now but the supplied sockadder::sa_family is: %hu",
+ ALOGE("ABinderRpc APIs only support AF_VSOCK right now but the supplied sockaddr::sa_family "
+ "is: %hu",
addr->sa_family);
return nullptr;
}
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 2f6c4e3..bd46c47 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -224,8 +224,10 @@
*
* Trace messages will use the provided names instead of bare integer codes when set. If not set by
* this function, trace messages will only be identified by the bare code. This should be called one
- * time during clazz initialization. clazz and transactionCodeToFunctionMap should have same
- * lifetime. Resetting/clearing the transactionCodeToFunctionMap is not allowed.
+ * time during clazz initialization. clazz is defined using AIBinder_Class_define and
+ * transactionCodeToFunctionMap should have same scope as clazz. Resetting/clearing the
+ * transactionCodeToFunctionMap is not allowed. Passing null for either clazz or
+ * transactionCodeToFunctionMap will abort.
*
* Available since API level 36.
*
@@ -236,9 +238,6 @@
* contiguous, and this is required for maximum memory efficiency.
* You can use nullptr if certain transaction codes are not used. Lifetime should be same as clazz.
* \param length number of elements in the transactionCodeToFunctionMap
- *
- * \return true if setting codeToFunction to clazz is successful. return false if clazz or
- * codeToFunction is nullptr.
*/
void AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class* clazz,
const char** transactionCodeToFunctionMap,
@@ -257,7 +256,8 @@
* \param transactionCode transaction_code_t for which function name is requested.
*
* \return function name in form of const char* if transaction code is valid for given class.
- * if transaction code is invalid or transactionCodeToFunctionMap is not set, nullptr is returned
+ * The value returned is valid for the lifetime of clazz. if transaction code is invalid or
+ * transactionCodeToFunctionMap is not set, nullptr is returned.
*/
const char* AIBinder_Class_getFunctionName(AIBinder_Class* clazz, transaction_code_t code)
__INTRODUCED_IN(36);
diff --git a/libs/binder/ndk/include_platform/android/binder_rpc.h b/libs/binder/ndk/include_platform/android/binder_rpc.h
index 4c5471f..7132554 100644
--- a/libs/binder/ndk/include_platform/android/binder_rpc.h
+++ b/libs/binder/ndk/include_platform/android/binder_rpc.h
@@ -22,6 +22,22 @@
__BEGIN_DECLS
/**
+ * @defgroup ABinderRpc Binder RPC
+ *
+ * This set of APIs makes it possible for a process to use the AServiceManager
+ * APIs to get binder objects for services that are available over sockets
+ * instead of the traditional kernel binder with the extra ServiceManager
+ * process.
+ *
+ * These APIs are used to supply libbinder with enough information to create
+ * and manage the socket connections underneath the ServiceManager APIs so the
+ * clients do not need to know the service implementation details or what
+ * transport they use for communication.
+ *
+ * @{
+ */
+
+/**
* This represents an IAccessor implementation from libbinder that is
* responsible for providing a pre-connected socket file descriptor for a
* specific service. The service is an RpcServer and the pre-connected socket is
@@ -66,7 +82,8 @@
* libbinder.
*
* \param instance name of the service like
- * `android.hardware.vibrator.IVibrator/default`
+ * `android.hardware.vibrator.IVibrator/default`. This string must remain
+ * valid and unchanged for the duration of this function call.
* \param data the data that was associated with this instance when the callback
* was registered.
* \return The ABinderRpc_Accessor associated with the service `instance`. This
@@ -103,13 +120,15 @@
* instance is being registered that was previously registered, this call
* will fail and the ABinderRpc_AccessorProviderUserData_deleteCallback
* will be called to clean up the data.
+ * This array of strings must remain valid and unchanged for the duration
+ * of this function call.
* \param number of instances in the instances array.
* \param data pointer that is passed to the ABinderRpc_AccessorProvider callback.
* IMPORTANT: The ABinderRpc_AccessorProvider now OWNS that object that data
* points to. It can be used as necessary in the callback. The data MUST
* remain valid for the lifetime of the provider callback.
* Do not attempt to give ownership of the same object to different
- * providers throguh multiple calls to this function because the first
+ * providers through multiple calls to this function because the first
* one to be deleted will call the onDelete callback.
* \param onDelete callback used to delete the objects that `data` points to.
* This is called after ABinderRpc_AccessorProvider is guaranteed to never be
@@ -151,8 +170,9 @@
* connect to a socket that a given service is listening on. This is needed to
* create an ABinderRpc_Accessor so it can connect to these services.
*
- * \param instance name of the service to connect to
- * \param data userdata for this callback. The pointer is provided in
+ * \param instance name of the service to connect to. This string must remain
+ * valid and unchanged for the duration of this function call.
+ * \param data user data for this callback. The pointer is provided in
* ABinderRpc_Accessor_new.
* \return ABinderRpc_ConnectionInfo with socket connection information for `instance`
*/
@@ -177,7 +197,9 @@
* that can use the info from the ABinderRpc_ConnectionInfoProvider to connect to a
* socket that the service with `instance` name is listening to.
*
- * \param instance name of the service that is listening on the socket
+ * \param instance name of the service that is listening on the socket. This
+ * string must remain valid and unchanged for the duration of this
+ * function call.
* \param provider callback that can get the socket connection information for the
* instance. This connection information may be dynamic, so the
* provider will be called any time a new connection is required.
@@ -219,18 +241,24 @@
/**
* Return the ABinderRpc_Accessor associated with an AIBinder. The instance must match
- * the ABinderRpc_Accessor implementation, and the AIBinder must a proxy binder for a
- * remote service (ABpBinder).
- * This can be used when receivng an AIBinder from another process that the
+ * the ABinderRpc_Accessor implementation.
+ * This can be used when receiving an AIBinder from another process that the
* other process obtained from ABinderRpc_Accessor_asBinder.
*
* \param instance name of the service that the Accessor is responsible for.
- * \param accessorBinder proxy binder from another processes ABinderRpc_Accessor.
+ * This string must remain valid and unchanged for the duration of this
+ * function call.
+ * \param accessorBinder proxy binder from another process's ABinderRpc_Accessor.
+ * This function preserves the refcount of this binder object and the
+ * caller still owns it.
* \return ABinderRpc_Accessor representing the other processes ABinderRpc_Accessor
- * implementation. This function does not take ownership of the
- * ABinderRpc_Accessor (so the caller needs to delete with
- * ABinderRpc_Accessor_delete), and it preserves the recount of the bidner
- * object.
+ * implementation. The caller owns this ABinderRpc_Accessor instance and
+ * is responsible for deleting it with ABinderRpc_Accessor_delete or
+ * passing ownership of it elsewhere, like returning it through
+ * ABinderRpc_AccessorProvider_getAccessorCallback.
+ * nullptr on error when the accessorBinder is not a valid binder from
+ * an IAccessor implementation or the IAccessor implementation is not
+ * associated with the provided instance.
*/
ABinderRpc_Accessor* _Nullable ABinderRpc_Accessor_fromBinder(const char* _Nonnull instance,
AIBinder* _Nonnull accessorBinder)
@@ -258,4 +286,6 @@
*/
void ABinderRpc_ConnectionInfo_delete(ABinderRpc_ConnectionInfo* _Nonnull info) __INTRODUCED_IN(36);
+/** @} */
+
__END_DECLS
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 2deb254..4545d7b 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -15,6 +15,8 @@
"libbinder_ndk_sys",
"libdowncast_rs",
"liblibc",
+ "liblog_rust",
+ "libnix",
],
host_supported: true,
vendor_available: true,
@@ -79,6 +81,9 @@
shared_libs: [
"libbinder_ndk",
],
+ rustlibs: [
+ "liblibc",
+ ],
host_supported: true,
vendor_available: true,
product_available: true,
@@ -129,9 +134,18 @@
// rustified
"libbinder_ndk_bindgen_flags.txt",
],
+ bindgen_flags: [
+ "--blocklist-type",
+ "sockaddr",
+ "--raw-line",
+ "use libc::sockaddr;",
+ ],
shared_libs: [
"libbinder_ndk",
],
+ rustlibs: [
+ "liblibc",
+ ],
host_supported: true,
vendor_available: true,
product_available: true,
@@ -185,6 +199,8 @@
"libbinder_ndk_sys",
"libdowncast_rs",
"liblibc",
+ "liblog_rust",
+ "libnix",
],
}
@@ -196,4 +212,7 @@
auto_gen_config: true,
clippy_lints: "none",
lints: "none",
+ rustlibs: [
+ "liblibc",
+ ],
}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index e048696..0e8e388 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -104,6 +104,8 @@
mod service;
#[cfg(not(trusty))]
mod state;
+#[cfg(not(any(android_vendor, android_vndk)))]
+mod system_only;
use binder_ndk_sys as sys;
@@ -120,6 +122,8 @@
};
#[cfg(not(trusty))]
pub use state::{ProcessState, ThreadState};
+#[cfg(not(any(android_vendor, android_vndk)))]
+pub use system_only::{Accessor, ConnectionInfo};
/// Binder result containing a [`Status`] on error.
pub type Result<T> = std::result::Result<T, Status>;
diff --git a/libs/binder/rust/src/system_only.rs b/libs/binder/rust/src/system_only.rs
new file mode 100644
index 0000000..a91d84d
--- /dev/null
+++ b/libs/binder/rust/src/system_only.rs
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::proxy::SpIBinder;
+use crate::sys;
+
+use std::ffi::{c_void, CStr, CString};
+use std::os::raw::c_char;
+
+use libc::sockaddr;
+use nix::sys::socket::{SockaddrLike, UnixAddr, VsockAddr};
+use std::sync::Arc;
+use std::{fmt, ptr};
+
+/// Rust wrapper around ABinderRpc_Accessor objects for RPC binder service management.
+///
+/// Dropping the `Accessor` will drop the underlying object and the binder it owns.
+pub struct Accessor {
+ accessor: *mut sys::ABinderRpc_Accessor,
+}
+
+impl fmt::Debug for Accessor {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "ABinderRpc_Accessor({:p})", self.accessor)
+ }
+}
+
+/// Socket connection info required for libbinder to connect to a service.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum ConnectionInfo {
+ /// For vsock connection
+ Vsock(VsockAddr),
+ /// For unix domain socket connection
+ Unix(UnixAddr),
+}
+
+/// Safety: A `Accessor` is a wrapper around `ABinderRpc_Accessor` which is
+/// `Sync` and `Send`. As
+/// `ABinderRpc_Accessor` is threadsafe, this structure is too.
+/// The Fn owned the Accessor has `Sync` and `Send` properties
+unsafe impl Send for Accessor {}
+
+/// Safety: A `Accessor` is a wrapper around `ABinderRpc_Accessor` which is
+/// `Sync` and `Send`. As `ABinderRpc_Accessor` is threadsafe, this structure is too.
+/// The Fn owned the Accessor has `Sync` and `Send` properties
+unsafe impl Sync for Accessor {}
+
+impl Accessor {
+ /// Create a new accessor that will call the given callback when its
+ /// connection info is required.
+ /// The callback object and all objects it captures are owned by the Accessor
+ /// and will be deleted some time after the Accessor is Dropped. If the callback
+ /// is being called when the Accessor is Dropped, the callback will not be deleted
+ /// immediately.
+ pub fn new<F>(instance: &str, callback: F) -> Accessor
+ where
+ F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,
+ {
+ let callback: *mut c_void = Arc::into_raw(Arc::new(callback)) as *mut c_void;
+ let inst = CString::new(instance).unwrap();
+
+ // Safety: The function pointer is a valid connection_info callback.
+ // This call returns an owned `ABinderRpc_Accessor` pointer which
+ // must be destroyed via `ABinderRpc_Accessor_delete` when no longer
+ // needed.
+ // When the underlying ABinderRpc_Accessor is deleted, it will call
+ // the cookie_decr_refcount callback to release its strong ref.
+ let accessor = unsafe {
+ sys::ABinderRpc_Accessor_new(
+ inst.as_ptr(),
+ Some(Self::connection_info::<F>),
+ callback,
+ Some(Self::cookie_decr_refcount::<F>),
+ )
+ };
+
+ Accessor { accessor }
+ }
+
+ /// Get the underlying binder for this Accessor for when it needs to be either
+ /// registered with service manager or sent to another process.
+ pub fn as_binder(&self) -> Option<SpIBinder> {
+ // Safety: `ABinderRpc_Accessor_asBinder` returns either a null pointer or a
+ // valid pointer to an owned `AIBinder`. Either of these values is safe to
+ // pass to `SpIBinder::from_raw`.
+ unsafe { SpIBinder::from_raw(sys::ABinderRpc_Accessor_asBinder(self.accessor)) }
+ }
+
+ /// Callback invoked from C++ when the connection info is needed.
+ ///
+ /// # Safety
+ ///
+ /// The `instance` parameter must be a non-null pointer to a valid C string for
+ /// CStr::from_ptr. The memory must contain a valid null terminator at the end of
+ /// the string within isize::MAX from the pointer. The memory must not be mutated for
+ /// the duration of this function call and must be valid for reads from the pointer
+ /// to the null terminator.
+ /// The `cookie` parameter must be the cookie for an `Arc<F>` and
+ /// the caller must hold a ref-count to it.
+ unsafe extern "C" fn connection_info<F>(
+ instance: *const c_char,
+ cookie: *mut c_void,
+ ) -> *mut binder_ndk_sys::ABinderRpc_ConnectionInfo
+ where
+ F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,
+ {
+ if cookie.is_null() || instance.is_null() {
+ log::error!("Cookie({cookie:p}) or instance({instance:p}) is null!");
+ return ptr::null_mut();
+ }
+ // Safety: The caller promises that `cookie` is for an Arc<F>.
+ let callback = unsafe { (cookie as *const F).as_ref().unwrap() };
+
+ // Safety: The caller in libbinder_ndk will have already verified this is a valid
+ // C string
+ let inst = unsafe {
+ match CStr::from_ptr(instance).to_str() {
+ Ok(s) => s,
+ Err(err) => {
+ log::error!("Failed to get a valid C string! {err:?}");
+ return ptr::null_mut();
+ }
+ }
+ };
+
+ let connection = match callback(inst) {
+ Some(con) => con,
+ None => {
+ return ptr::null_mut();
+ }
+ };
+
+ match connection {
+ ConnectionInfo::Vsock(addr) => {
+ // Safety: The sockaddr is being copied in the NDK API
+ unsafe { sys::ABinderRpc_ConnectionInfo_new(addr.as_ptr(), addr.len()) }
+ }
+ ConnectionInfo::Unix(addr) => {
+ // Safety: The sockaddr is being copied in the NDK API
+ // The cast is from sockaddr_un* to sockaddr*.
+ unsafe {
+ sys::ABinderRpc_ConnectionInfo_new(addr.as_ptr() as *const sockaddr, addr.len())
+ }
+ }
+ }
+ }
+
+ /// Callback that decrements the ref-count.
+ /// This is invoked from C++ when a binder is unlinked.
+ ///
+ /// # Safety
+ ///
+ /// The `cookie` parameter must be the cookie for an `Arc<F>` and
+ /// the owner must give up a ref-count to it.
+ unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
+ where
+ F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,
+ {
+ // Safety: The caller promises that `cookie` is for an Arc<F>.
+ unsafe { Arc::decrement_strong_count(cookie as *const F) };
+ }
+}
+
+impl Drop for Accessor {
+ fn drop(&mut self) {
+ // Safety: `self.accessor` is always a valid, owned
+ // `ABinderRpc_Accessor` pointer returned by
+ // `ABinderRpc_Accessor_new` when `self` was created. This delete
+ // method can only be called once when `self` is dropped.
+ unsafe {
+ sys::ABinderRpc_Accessor_delete(self.accessor);
+ }
+ }
+}
diff --git a/libs/binder/rust/sys/BinderBindings.hpp b/libs/binder/rust/sys/BinderBindings.hpp
index 65fa2ca..bd666fe 100644
--- a/libs/binder/rust/sys/BinderBindings.hpp
+++ b/libs/binder/rust/sys/BinderBindings.hpp
@@ -20,6 +20,7 @@
#include <android/binder_parcel.h>
#include <android/binder_parcel_platform.h>
#include <android/binder_process.h>
+#include <android/binder_rpc.h>
#include <android/binder_shell.h>
#include <android/binder_stability.h>
#include <android/binder_status.h>
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 5359832..bdb7e4a 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -384,8 +384,8 @@
use std::time::Duration;
use binder::{
- BinderFeatures, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode,
- Strong,
+ Accessor, BinderFeatures, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder,
+ StatusCode, Strong,
};
// Import from impl API for testing only, should not be necessary as long as
// you are using AIDL.
@@ -908,6 +908,43 @@
assert_eq!(service.test().unwrap(), service_name);
}
+ struct ToBeDeleted {
+ deleted: Arc<AtomicBool>,
+ }
+
+ impl Drop for ToBeDeleted {
+ fn drop(&mut self) {
+ assert!(!self.deleted.load(Ordering::Relaxed));
+ self.deleted.store(true, Ordering::Relaxed);
+ }
+ }
+
+ #[test]
+ fn test_accessor_callback_destruction() {
+ let deleted: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
+ {
+ let accessor: Accessor;
+ {
+ let helper = ToBeDeleted { deleted: deleted.clone() };
+ let get_connection_info = move |_instance: &str| {
+ // Capture this object so we can see it get destructed
+ // after the parent scope
+ let _ = &helper;
+ None
+ };
+ accessor = Accessor::new("foo.service", get_connection_info);
+ }
+
+ match accessor.as_binder() {
+ Some(_) => {
+ assert!(!deleted.load(Ordering::Relaxed));
+ }
+ None => panic!("failed to get that accessor binder"),
+ }
+ }
+ assert!(deleted.load(Ordering::Relaxed));
+ }
+
#[tokio::test]
async fn reassociate_rust_binder_async() {
let service_name = "testing_service";
diff --git a/libs/binder/tests/binderCacheUnitTest.cpp b/libs/binder/tests/binderCacheUnitTest.cpp
index 482d197..be5d559 100644
--- a/libs/binder/tests/binderCacheUnitTest.cpp
+++ b/libs/binder/tests/binderCacheUnitTest.cpp
@@ -149,7 +149,16 @@
EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
// Confirm that new service is returned instead of old.
- sp<IBinder> result2 = mServiceManager->checkService(kCachedServiceName);
+ int retry_count = 5;
+ sp<IBinder> result2;
+ do {
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ if (retry_count-- == 0) {
+ break;
+ }
+ result2 = mServiceManager->checkService(kCachedServiceName);
+ } while (result2 != binder2);
+
ASSERT_EQ(binder2, result2);
}
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index fbab8f0..cac054e 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -39,6 +39,7 @@
"smoreland@google.com",
"waghpawan@google.com",
],
+ triage_assignee: "smoreland@google.com",
use_for_presubmit: true,
},