diff options
author | 2022-03-23 21:46:32 +0000 | |
---|---|---|
committer | 2022-03-30 22:31:44 +0000 | |
commit | 21e09430ebd3044c88f680478e81f0131b58b470 (patch) | |
tree | c573dfb15b052c897eb8538080bc3f1fc5e4ca37 | |
parent | a3eab26a641c071b714a6cf578be7c7ae5b8c8d3 (diff) |
Don't allow std::make_shared/unique for ndk::SharedRefBase objects
Bug: 226379467
Test: TH
Change-Id: Id80deea18e87de02f09e456997b8d2738d030489
-rw-r--r-- | libs/binder/ndk/include_cpp/android/binder_interface_utils.h | 38 | ||||
-rw-r--r-- | libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp | 3 |
2 files changed, 39 insertions, 2 deletions
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h index b3bc7f449e..c8e78fc55d 100644 --- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h +++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h @@ -324,4 +324,42 @@ SpAIBinder BpCInterface<INTERFACE>::asBinder() { } // namespace ndk +// Once minSdkVersion is 30, we are guaranteed to be building with the +// Android 11 AIDL compiler which supports the SharedRefBase::make API. +#if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30 || defined(__ANDROID_APEX__) +namespace ndk::internal { +template <typename T, typename = void> +struct is_complete_type : std::false_type {}; + +template <typename T> +struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {}; +} // namespace ndk::internal + +namespace std { + +// Define `SharedRefBase` specific versions of `std::make_shared` and +// `std::make_unique` to block people from using them. Using them to allocate +// `ndk::SharedRefBase` objects results in double ownership. Use +// `ndk::SharedRefBase::make<T>(...)` instead. +// +// Note: We exclude incomplete types because `std::is_base_of` is undefined in +// that case. + +template <typename T, typename... Args, + std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true, + std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true> +shared_ptr<T> make_shared(Args...) { // SEE COMMENT ABOVE. + static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value); +} + +template <typename T, typename... Args, + std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true, + std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true> +unique_ptr<T> make_unique(Args...) { // SEE COMMENT ABOVE. + static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value); +} + +} // namespace std +#endif + /** @} */ diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index 357b454f7f..1b136dcb8e 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -231,8 +231,7 @@ TEST(NdkBinder, DetectDoubleOwn) { } TEST(NdkBinder, DetectNoSharedRefBaseCreated) { - EXPECT_DEATH(std::make_shared<MyBinderNdkUnitTest>(), - "SharedRefBase: no ref created during lifetime"); + EXPECT_DEATH(MyBinderNdkUnitTest(), "SharedRefBase: no ref created during lifetime"); } TEST(NdkBinder, GetServiceThatDoesntExist) { |