summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Frederick Mayle <fmayle@google.com> 2022-03-31 02:00:01 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2022-03-31 02:00:01 +0000
commit6530a48dc81a9f19075a65edd120b8141b6eb97b (patch)
tree1e270e0c59dcba67b56ff2ddb1cb190397817316
parentdb327772754d48c7f4f01192186ecab1a5c4bf6e (diff)
parentb4b793e82826a020cda66ddaed5519fed64d0e03 (diff)
Merge "Don't allow std::make_shared/unique for ndk::SharedRefBase objects" into tm-dev am: b4b793e828
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/17355019 Change-Id: Ic5e0953ebca5ba6dcd2f5e5932adb70578024eb0 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--libs/binder/ndk/include_cpp/android/binder_interface_utils.h38
-rw-r--r--libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp3
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) {