diff options
| -rw-r--r-- | libs/binder/ndk/binder_rpc.cpp | 16 | ||||
| -rw-r--r-- | libs/binder/ndk/include_platform/android/binder_rpc.h | 2 | ||||
| -rw-r--r-- | libs/binder/tests/binderRpcTest.cpp | 20 |
3 files changed, 30 insertions, 8 deletions
diff --git a/libs/binder/ndk/binder_rpc.cpp b/libs/binder/ndk/binder_rpc.cpp index 53ab68e643..bb5989dec8 100644 --- a/libs/binder/ndk/binder_rpc.cpp +++ b/libs/binder/ndk/binder_rpc.cpp @@ -107,16 +107,20 @@ ABinderRpc_AccessorProvider* ABinderRpc_registerAccessorProvider( 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 @@ ABinderRpc_AccessorProvider* ABinderRpc_registerAccessorProvider( 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 7d54e2dad9..13188894be 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 @@ typedef void (*ABinderRpc_AccessorProviderUserData_deleteCallback)(void* _Nullab * 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 506fc716cd..da5a8e3881 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -1400,6 +1400,26 @@ TEST_F(BinderARpcNdk, ARpcProviderNewDelete) { 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; |