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,
     },