Delete user data even on error when registering AccessorProviders

If ABinderRpc_registerAccessorProvider returns nullptr on error, we need
to make sure we still call the delete callback on the user data as the
user expects to be giving up ownership of it when they make the call.

Test: atest binderRpcTest
Bug: 358427181
Change-Id: I049e33f88ba202cd97e970276b50903374131eff
diff --git a/libs/binder/ndk/binder_rpc.cpp b/libs/binder/ndk/binder_rpc.cpp
index 53ab68e..bb5989d 100644
--- a/libs/binder/ndk/binder_rpc.cpp
+++ b/libs/binder/ndk/binder_rpc.cpp
@@ -107,16 +107,20 @@
         ABinderRpc_AccessorProvider_getAccessorCallback provider,
         const char* const* const instances, size_t numInstances, void* data,
         ABinderRpc_AccessorProviderUserData_deleteCallback onDelete) {
-    if (provider == nullptr) {
-        ALOGE("Null provider passed to ABinderRpc_registerAccessorProvider");
-        return nullptr;
-    }
     if (data && onDelete == nullptr) {
         ALOGE("If a non-null data ptr is passed to ABinderRpc_registerAccessorProvider, then a "
               "ABinderRpc_AccessorProviderUserData_deleteCallback must also be passed to delete "
               "the data object once the ABinderRpc_AccessorProvider is removed.");
         return nullptr;
     }
+    // call the onDelete when the last reference of this goes away (when the
+    // last reference to the generate std::function goes away).
+    std::shared_ptr<OnDeleteProviderHolder> onDeleteHolder =
+            std::make_shared<OnDeleteProviderHolder>(data, onDelete);
+    if (provider == nullptr) {
+        ALOGE("Null provider passed to ABinderRpc_registerAccessorProvider");
+        return nullptr;
+    }
     if (numInstances == 0 || instances == nullptr) {
         ALOGE("No instances passed to ABinderRpc_registerAccessorProvider. numInstances: %zu",
               numInstances);
@@ -126,10 +130,6 @@
     for (size_t i = 0; i < numInstances; i++) {
         instanceStrings.emplace(instances[i]);
     }
-    // call the onDelete when the last reference of this goes away (when the
-    // last reference to the generate std::function goes away).
-    std::shared_ptr<OnDeleteProviderHolder> onDeleteHolder =
-            std::make_shared<OnDeleteProviderHolder>(data, onDelete);
     android::RpcAccessorProvider generate = [provider,
                                              onDeleteHolder](const String16& name) -> sp<IBinder> {
         ABinderRpc_Accessor* accessor = provider(String8(name).c_str(), onDeleteHolder->mData);
diff --git a/libs/binder/ndk/include_platform/android/binder_rpc.h b/libs/binder/ndk/include_platform/android/binder_rpc.h
index 7d54e2d..1318889 100644
--- a/libs/binder/ndk/include_platform/android/binder_rpc.h
+++ b/libs/binder/ndk/include_platform/android/binder_rpc.h
@@ -139,6 +139,8 @@
  *         registered. In the error case of duplicate instances, if data was
  *         provided with a ABinderRpc_AccessorProviderUserData_deleteCallback,
  *         the callback will be called to delete the data.
+ *         If nullptr is returned, ABinderRpc_AccessorProviderUserData_deleteCallback
+ *         will be called on data immediately.
  *         Otherwise returns a pointer to the ABinderRpc_AccessorProvider that
  *         can be used to remove with ABinderRpc_unregisterAccessorProvider.
  */
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 506fc71..da5a8e3 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -1400,6 +1400,26 @@
     EXPECT_TRUE(isDeleted);
 }
 
+TEST_F(BinderARpcNdk, ARpcProviderDeleteOnError) {
+    bool isDeleted = false;
+    AccessorProviderData* data = new AccessorProviderData{{}, 0, &isDeleted};
+
+    ABinderRpc_AccessorProvider* provider =
+            ABinderRpc_registerAccessorProvider(getAccessor, kARpcSupportedServices, 0, data,
+                                                accessorProviderDataOnDelete);
+
+    ASSERT_EQ(provider, nullptr);
+    EXPECT_TRUE(isDeleted);
+}
+
+TEST_F(BinderARpcNdk, ARpcProvideOnErrorNoDeleteCbNoCrash) {
+    ABinderRpc_AccessorProvider* provider =
+            ABinderRpc_registerAccessorProvider(getAccessor, kARpcSupportedServices, 0, nullptr,
+                                                nullptr);
+
+    ASSERT_EQ(provider, nullptr);
+}
+
 TEST_F(BinderARpcNdk, ARpcProviderDuplicateInstance) {
     const char* instance = "some.instance.name.IFoo/default";
     const uint32_t numInstances = 2;