Loading cmds/installd/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ cc_defaults { "libutils", "server_configurable_flags", ], export_shared_lib_headers: [ "libbinder", ], product_variables: { arc: { Loading libs/binder/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ cc_library_headers { header_libs: [ "libbase_headers", "libbinder_headers_platform_shared", "libcutils_headers", "libutils_headers", ], export_header_lib_headers: [ "libbase_headers", "libbinder_headers_platform_shared", "libcutils_headers", "libutils_headers", ], Loading libs/binder/ndk/Android.bp +22 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,28 @@ cc_library { ], } cc_library_headers { name: "libbinder_headers_platform_shared", export_include_dirs: ["include_cpp"], vendor_available: true, host_supported: true, // TODO(b/153609531): remove when no longer needed. native_bridge_supported: true, target: { darwin: { enabled: false, }, }, min_sdk_version: "29", apex_available: [ "//apex_available:platform", // TODO(b/166468760) remove these three "com.android.media", "com.android.media.swcodec", "test_com.android.media.swcodec", ], } ndk_headers { name: "libbinder_ndk_headers", from: "include_ndk/android", Loading libs/binder/ndk/include_cpp/android/binder_to_string.h 0 → 100644 +184 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. */ /** * @addtogroup NdkBinder * @{ */ /** * @file binder_to_string.h * @brief Helper for parcelable. */ #pragma once #include <codecvt> #include <locale> #include <sstream> #include <string> #include <type_traits> #if __has_include(<android/binder_ibinder.h>) #include <android/binder_auto_utils.h> #include <android/binder_interface_utils.h> #include <android/binder_parcelable_utils.h> #define HAS_NDK_INTERFACE #else #include <binder/IBinder.h> #include <binder/IInterface.h> #include <binder/ParcelFileDescriptor.h> #include <binder/ParcelableHolder.h> #include <utils/String16.h> #include <utils/StrongPointer.h> #define HAS_CPP_INTERFACE #endif //_has_include namespace android { namespace internal { // ToString is a utility to generate string representation for various AIDL-supported types. template <typename _T> std::string ToString(const _T& t); namespace details { // Truthy if _T has toString() method. template <typename _T> class HasToStringMethod { template <typename _U> static auto _test(int) -> decltype(std::declval<_U>().toString(), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T has a overloaded toString(T) template <typename _T> class HasToStringFunction { template <typename _U> static auto _test(int) -> decltype(toString(std::declval<_U>()), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T is like a pointer template <typename _T> class IsPointerLike { template <typename _U> static auto _test(int) -> decltype(!std::declval<_U>(), *std::declval<_U>(), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T is like a container template <typename _T> class IsIterable { template <typename _U> static auto _test(int) -> decltype(begin(std::declval<_U>()), end(std::declval<_U>()), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; template <typename _T> class ToEmptyString { template <typename _U> static std::enable_if_t< #ifdef HAS_NDK_INTERFACE std::is_base_of_v<::ndk::ICInterface, _U> || std::is_same_v<::ndk::SpAIBinder, _U> || std::is_same_v<::ndk::ScopedFileDescriptor, _U> || std::is_same_v<::ndk::AParcelableHolder, _U> #else std::is_base_of_v<IInterface, _U> || std::is_same_v<IBinder, _U> || std::is_same_v<os::ParcelFileDescriptor, _U> || std::is_same_v<os::ParcelableHolder, _U> #endif , std::true_type> _test(int); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; } // namespace details template <typename _T> std::string ToString(const _T& t) { if constexpr (details::ToEmptyString<_T>::value) { return ""; } else if constexpr (std::is_same_v<bool, _T>) { return t ? "true" : "false"; } else if constexpr (std::is_same_v<char16_t, _T>) { return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().to_bytes(t); } else if constexpr (std::is_arithmetic_v<_T>) { return std::to_string(t); } else if constexpr (std::is_same_v<std::string, _T>) { return t; #ifdef HAS_CPP_INTERFACE } else if constexpr (std::is_same_v<String16, _T>) { std::stringstream out; out << t; return out.str(); #endif } else if constexpr (details::HasToStringMethod<_T>::value) { return t.toString(); } else if constexpr (details::HasToStringFunction<_T>::value) { return toString(t); } else if constexpr (details::IsIterable<_T>::value) { std::stringstream out; bool first = true; out << "["; for (const auto& e : t) { if (first) { first = false; } else { out << ", "; } // Use explicit type parameter in case deref of iterator has different type // e.g. vector<bool> out << ToString<typename _T::value_type>(e); } out << "]"; return out.str(); } else if constexpr (details::IsPointerLike<_T>::value) { if (!t) return "(null)"; std::stringstream out; out << ToString(*t); return out.str(); } else { return "{no toString() implemented}"; } } } // namespace internal } // namespace android /** @} */ libs/binder/tests/Android.bp +12 −0 Original line number Diff line number Diff line Loading @@ -220,3 +220,15 @@ cc_test { test_suites: ["device-tests"], require_root: true, } cc_benchmark { name: "binderParcelBenchmark", defaults: ["binder_test_defaults"], srcs: ["binderParcelBenchmark.cpp"], shared_libs: [ "libbase", "libbinder", "liblog", "libutils", ], } Loading
cmds/installd/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ cc_defaults { "libutils", "server_configurable_flags", ], export_shared_lib_headers: [ "libbinder", ], product_variables: { arc: { Loading
libs/binder/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ cc_library_headers { header_libs: [ "libbase_headers", "libbinder_headers_platform_shared", "libcutils_headers", "libutils_headers", ], export_header_lib_headers: [ "libbase_headers", "libbinder_headers_platform_shared", "libcutils_headers", "libutils_headers", ], Loading
libs/binder/ndk/Android.bp +22 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,28 @@ cc_library { ], } cc_library_headers { name: "libbinder_headers_platform_shared", export_include_dirs: ["include_cpp"], vendor_available: true, host_supported: true, // TODO(b/153609531): remove when no longer needed. native_bridge_supported: true, target: { darwin: { enabled: false, }, }, min_sdk_version: "29", apex_available: [ "//apex_available:platform", // TODO(b/166468760) remove these three "com.android.media", "com.android.media.swcodec", "test_com.android.media.swcodec", ], } ndk_headers { name: "libbinder_ndk_headers", from: "include_ndk/android", Loading
libs/binder/ndk/include_cpp/android/binder_to_string.h 0 → 100644 +184 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. */ /** * @addtogroup NdkBinder * @{ */ /** * @file binder_to_string.h * @brief Helper for parcelable. */ #pragma once #include <codecvt> #include <locale> #include <sstream> #include <string> #include <type_traits> #if __has_include(<android/binder_ibinder.h>) #include <android/binder_auto_utils.h> #include <android/binder_interface_utils.h> #include <android/binder_parcelable_utils.h> #define HAS_NDK_INTERFACE #else #include <binder/IBinder.h> #include <binder/IInterface.h> #include <binder/ParcelFileDescriptor.h> #include <binder/ParcelableHolder.h> #include <utils/String16.h> #include <utils/StrongPointer.h> #define HAS_CPP_INTERFACE #endif //_has_include namespace android { namespace internal { // ToString is a utility to generate string representation for various AIDL-supported types. template <typename _T> std::string ToString(const _T& t); namespace details { // Truthy if _T has toString() method. template <typename _T> class HasToStringMethod { template <typename _U> static auto _test(int) -> decltype(std::declval<_U>().toString(), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T has a overloaded toString(T) template <typename _T> class HasToStringFunction { template <typename _U> static auto _test(int) -> decltype(toString(std::declval<_U>()), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T is like a pointer template <typename _T> class IsPointerLike { template <typename _U> static auto _test(int) -> decltype(!std::declval<_U>(), *std::declval<_U>(), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T is like a container template <typename _T> class IsIterable { template <typename _U> static auto _test(int) -> decltype(begin(std::declval<_U>()), end(std::declval<_U>()), std::true_type()); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; template <typename _T> class ToEmptyString { template <typename _U> static std::enable_if_t< #ifdef HAS_NDK_INTERFACE std::is_base_of_v<::ndk::ICInterface, _U> || std::is_same_v<::ndk::SpAIBinder, _U> || std::is_same_v<::ndk::ScopedFileDescriptor, _U> || std::is_same_v<::ndk::AParcelableHolder, _U> #else std::is_base_of_v<IInterface, _U> || std::is_same_v<IBinder, _U> || std::is_same_v<os::ParcelFileDescriptor, _U> || std::is_same_v<os::ParcelableHolder, _U> #endif , std::true_type> _test(int); template <typename _U> static std::false_type _test(...); public: enum { value = decltype(_test<_T>(0))::value }; }; } // namespace details template <typename _T> std::string ToString(const _T& t) { if constexpr (details::ToEmptyString<_T>::value) { return ""; } else if constexpr (std::is_same_v<bool, _T>) { return t ? "true" : "false"; } else if constexpr (std::is_same_v<char16_t, _T>) { return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().to_bytes(t); } else if constexpr (std::is_arithmetic_v<_T>) { return std::to_string(t); } else if constexpr (std::is_same_v<std::string, _T>) { return t; #ifdef HAS_CPP_INTERFACE } else if constexpr (std::is_same_v<String16, _T>) { std::stringstream out; out << t; return out.str(); #endif } else if constexpr (details::HasToStringMethod<_T>::value) { return t.toString(); } else if constexpr (details::HasToStringFunction<_T>::value) { return toString(t); } else if constexpr (details::IsIterable<_T>::value) { std::stringstream out; bool first = true; out << "["; for (const auto& e : t) { if (first) { first = false; } else { out << ", "; } // Use explicit type parameter in case deref of iterator has different type // e.g. vector<bool> out << ToString<typename _T::value_type>(e); } out << "]"; return out.str(); } else if constexpr (details::IsPointerLike<_T>::value) { if (!t) return "(null)"; std::stringstream out; out << ToString(*t); return out.str(); } else { return "{no toString() implemented}"; } } } // namespace internal } // namespace android /** @} */
libs/binder/tests/Android.bp +12 −0 Original line number Diff line number Diff line Loading @@ -220,3 +220,15 @@ cc_test { test_suites: ["device-tests"], require_root: true, } cc_benchmark { name: "binderParcelBenchmark", defaults: ["binder_test_defaults"], srcs: ["binderParcelBenchmark.cpp"], shared_libs: [ "libbase", "libbinder", "liblog", "libutils", ], }