Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44eabf62 authored by Jooyung Han's avatar Jooyung Han Committed by Automerger Merge Worker
Browse files

Add a shared header lib for libbinder/libbinder_ndk am: caede598 am: 22377d29

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1574060

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I5707475c670859376a4156bb57180991b21350e0
parents 2f62ffee 22377d29
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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",
    ],
+22 −0
Original line number Diff line number Diff line
@@ -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",
+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

/** @} */