diff options
author | 2024-09-18 02:46:35 +0000 | |
---|---|---|
committer | 2024-09-18 02:46:52 +0000 | |
commit | 07198ad6b5fd6c8f4b43f9eb803330b5226323ed (patch) | |
tree | 0825bb11a96beb1a41aab2adb1efb9242909d5b6 | |
parent | 358953fe5f6089bf022e0e9bc0f564122f53eb9a (diff) |
Revert "Move tracing calls to libbinder_ndk"
Revert submission 3208491-ndk_trace
Reason for revert: Droidmonitor created revert due to b/367848545. Will be verifying through ABTD before submission.
Reverted changes: /q/submissionid:3208491-ndk_trace
Change-Id: I65644515b15b60c9b828f795b354befa74b911f5
-rw-r--r-- | libs/binder/OS.h | 1 | ||||
-rw-r--r-- | libs/binder/OS_android.cpp | 4 | ||||
-rw-r--r-- | libs/binder/OS_non_android_linux.cpp | 4 | ||||
-rw-r--r-- | libs/binder/include/binder/Trace.h | 1 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder.cpp | 133 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder_internal.h | 7 | ||||
-rw-r--r-- | libs/binder/ndk/include_cpp/android/binder_interface_utils.h | 26 | ||||
-rw-r--r-- | libs/binder/ndk/include_ndk/android/binder_ibinder.h | 57 | ||||
-rw-r--r-- | libs/binder/ndk/libbinder_ndk.map.txt | 8 | ||||
-rw-r--r-- | libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp | 31 | ||||
-rw-r--r-- | libs/binder/tests/parcel_fuzzer/binder_ndk.cpp | 3 | ||||
-rw-r--r-- | libs/binder/trusty/OS.cpp | 4 | ||||
-rw-r--r-- | libs/binder/trusty/ndk/include/android/llndk-versioning.h | 2 |
13 files changed, 7 insertions, 274 deletions
diff --git a/libs/binder/OS.h b/libs/binder/OS.h index 64b1fd48fd..04869a170f 100644 --- a/libs/binder/OS.h +++ b/libs/binder/OS.h @@ -27,7 +27,6 @@ namespace android::binder::os { LIBBINDER_EXPORTED void trace_begin(uint64_t tag, const char* name); LIBBINDER_EXPORTED void trace_end(uint64_t tag); LIBBINDER_EXPORTED void trace_int(uint64_t tag, const char* name, int32_t value); -LIBBINDER_EXPORTED uint64_t get_trace_enabled_tags(); status_t setNonBlocking(borrowed_fd fd); diff --git a/libs/binder/OS_android.cpp b/libs/binder/OS_android.cpp index 4e9230ce58..893ee15578 100644 --- a/libs/binder/OS_android.cpp +++ b/libs/binder/OS_android.cpp @@ -48,10 +48,6 @@ void trace_int(uint64_t tag, const char* name, int32_t value) { atrace_int(tag, name, value); } -uint64_t get_trace_enabled_tags() { - return atrace_enabled_tags; -} - } // namespace os // Legacy trace symbol. To be removed once all of downstream rebuilds. diff --git a/libs/binder/OS_non_android_linux.cpp b/libs/binder/OS_non_android_linux.cpp index 6bba823897..0c64eb61c6 100644 --- a/libs/binder/OS_non_android_linux.cpp +++ b/libs/binder/OS_non_android_linux.cpp @@ -41,10 +41,6 @@ void trace_end(uint64_t) {} void trace_int(uint64_t, const char*, int32_t) {} -uint64_t get_trace_enabled_tags() { - return 0; -} - uint64_t GetThreadId() { return syscall(__NR_gettid); } diff --git a/libs/binder/include/binder/Trace.h b/libs/binder/include/binder/Trace.h index a3e6c8a12b..2f450cb36b 100644 --- a/libs/binder/include/binder/Trace.h +++ b/libs/binder/include/binder/Trace.h @@ -42,7 +42,6 @@ namespace os { void trace_begin(uint64_t tag, const char* name); void trace_end(uint64_t tag); void trace_int(uint64_t tag, const char* name, int32_t value); -uint64_t get_trace_enabled_tags(); } // namespace os class LIBBINDER_EXPORTED ScopedTrace { diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index ff31dd0193..af280d38a3 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -18,10 +18,8 @@ #include <android/binder_ibinder_platform.h> #include <android/binder_stability.h> #include <android/binder_status.h> -#include <binder/Functional.h> #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> -#include <binder/Trace.h> #if __has_include(<private/android_filesystem_config.h>) #include <private/android_filesystem_config.h> #endif @@ -42,23 +40,6 @@ using ::android::statusToString; using ::android::String16; using ::android::String8; using ::android::wp; -using ::android::binder::impl::make_scope_guard; -using ::android::binder::impl::scope_guard; -using ::android::binder::os::get_trace_enabled_tags; -using ::android::binder::os::trace_begin; -using ::android::binder::os::trace_end; - -// transaction codes for getInterfaceHash and getInterfaceVersion are defined -// in file : system/tools/aidl/aidl.cpp -static constexpr int kGetInterfaceVersionId = 0x00fffffe; -static const char* kInterfaceVersion = "getInterfaceVersion"; -static constexpr int kGetInterfaceHashId = 0x00fffffd; -static const char* kInterfaceHash = "getInterfaceHash"; -static const char* kNdkTrace = "AIDL::ndk::"; -static const char* kServerTrace = "::server"; -static const char* kClientTrace = "::client"; -static const char* kSeparator = "::"; -static const char* kUnknownCode = "Unknown_Transaction_Code:"; namespace ABBinderTag { @@ -109,51 +90,6 @@ static std::string SanitizeString(const String16& str) { return sanitized; } -const std::string getMethodName(const AIBinder_Class* clazz, transaction_code_t code) { - // TODO(b/150155678) - Move getInterfaceHash and getInterfaceVersion to libbinder and remove - // hardcoded cases. - if (code <= clazz->getTransactionCodeToFunctionLength() && code >= FIRST_CALL_TRANSACTION) { - // Codes have FIRST_CALL_TRANSACTION as added offset. Subtract to access function name - return clazz->getFunctionName(code); - } else if (code == kGetInterfaceVersionId) { - return kInterfaceVersion; - } else if (code == kGetInterfaceHashId) { - return kInterfaceHash; - } - return kUnknownCode + std::to_string(code); -} - -const std::string getTraceSectionName(const AIBinder_Class* clazz, transaction_code_t code, - bool isServer) { - if (clazz == nullptr) { - ALOGE("class associated with binder is null. Class is needed to add trace with interface " - "name and function name"); - return kNdkTrace; - } - - const std::string descriptor = clazz->getInterfaceDescriptorUtf8(); - const std::string methodName = getMethodName(clazz, code); - - size_t traceSize = - strlen(kNdkTrace) + descriptor.size() + strlen(kSeparator) + methodName.size(); - traceSize += isServer ? strlen(kServerTrace) : strlen(kClientTrace); - - std::string trace; - // reserve to avoid repeated allocations - trace.reserve(traceSize); - - trace += kNdkTrace; - trace += clazz->getInterfaceDescriptorUtf8(); - trace += kSeparator; - trace += methodName; - trace += isServer ? kServerTrace : kClientTrace; - - LOG_ALWAYS_FATAL_IF(trace.size() != traceSize, "Trace size mismatch. Expected %zu, got %zu", - traceSize, trace.size()); - - return trace; -} - bool AIBinder::associateClass(const AIBinder_Class* clazz) { if (clazz == nullptr) return false; @@ -267,17 +203,6 @@ status_t ABBinder::dump(int fd, const ::android::Vector<String16>& args) { status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply, binder_flags_t flags) { - std::string sectionName; - bool tracingEnabled = get_trace_enabled_tags() & ATRACE_TAG_AIDL; - if (tracingEnabled) { - sectionName = getTraceSectionName(getClass(), code, true /*isServer*/); - trace_begin(ATRACE_TAG_AIDL, sectionName.c_str()); - } - - scope_guard guard = make_scope_guard([&]() { - if (tracingEnabled) trace_end(ATRACE_TAG_AIDL); - }); - if (isUserCommand(code)) { if (getClass()->writeHeader && !data.checkInterface(this)) { return STATUS_BAD_TYPE; @@ -460,31 +385,6 @@ AIBinder_Class::AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_o mInterfaceDescriptor(interfaceDescriptor), mWideInterfaceDescriptor(interfaceDescriptor) {} -bool AIBinder_Class::setTransactionCodeMap(const char** transactionCodeMap, size_t length) { - if (mTransactionCodeToFunction != nullptr) { - ALOGE("mTransactionCodeToFunction is already set!"); - return false; - } - mTransactionCodeToFunction = transactionCodeMap; - mTransactionCodeToFunctionLength = length; - return true; -} - -const char* AIBinder_Class::getFunctionName(transaction_code_t code) const { - if (mTransactionCodeToFunction == nullptr) { - ALOGE("mTransactionCodeToFunction is not set!"); - return nullptr; - } - - if (code < FIRST_CALL_TRANSACTION || - code - FIRST_CALL_TRANSACTION >= mTransactionCodeToFunctionLength) { - ALOGE("Function name for requested code not found!"); - return nullptr; - } - - return mTransactionCodeToFunction[code - FIRST_CALL_TRANSACTION]; -} - AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate, AIBinder_Class_onDestroy onDestroy, @@ -504,24 +404,6 @@ void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) { clazz->onDump = onDump; } -void AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class* clazz, - const char** transactionCodeToFunction, - size_t length) { - LOG_ALWAYS_FATAL_IF(clazz == nullptr || transactionCodeToFunction == nullptr, - "Valid clazz and transactionCodeToFunction are needed to set code to " - "function mapping."); - LOG_ALWAYS_FATAL_IF(!clazz->setTransactionCodeMap(transactionCodeToFunction, length), - "Failed to set transactionCodeToFunction to clazz! Is " - "transactionCodeToFunction already set?"); -} - -const char* AIBinder_Class_getFunctionName(AIBinder_Class* clazz, transaction_code_t code) { - LOG_ALWAYS_FATAL_IF( - clazz == nullptr, - "Valid clazz is needed to get function name for requested transaction code"); - return clazz->getFunctionName(code); -} - void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) { LOG_ALWAYS_FATAL_IF(clazz == nullptr, "disableInterfaceTokenHeader requires non-null clazz"); @@ -852,19 +734,6 @@ static void DestroyParcel(AParcel** parcel) { binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in, AParcel** out, binder_flags_t flags) { - const AIBinder_Class* clazz = binder ? binder->getClass() : nullptr; - - std::string sectionName; - bool tracingEnabled = get_trace_enabled_tags() & ATRACE_TAG_AIDL; - if (tracingEnabled) { - sectionName = getTraceSectionName(clazz, code, false /*isServer*/); - trace_begin(ATRACE_TAG_AIDL, sectionName.c_str()); - } - - scope_guard guard = make_scope_guard([&]() { - if (tracingEnabled) trace_end(ATRACE_TAG_AIDL); - }); - if (in == nullptr) { ALOGE("%s: requires non-null in parameter", __func__); return STATUS_UNEXPECTED_NULL; @@ -1003,4 +872,4 @@ void AIBinder_setInheritRt(AIBinder* binder, bool inheritRt) { "AIBinder_setInheritRt must be called on a local binder"); localBinder->setInheritRt(inheritRt); -}
\ No newline at end of file +} diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h index a93dc1f674..f5b738c1ef 100644 --- a/libs/binder/ndk/ibinder_internal.h +++ b/libs/binder/ndk/ibinder_internal.h @@ -132,9 +132,6 @@ struct AIBinder_Class { const ::android::String16& getInterfaceDescriptor() const { return mWideInterfaceDescriptor; } const char* getInterfaceDescriptorUtf8() const { return mInterfaceDescriptor.c_str(); } - bool setTransactionCodeMap(const char** transactionCodeMap, size_t transactionCodeMapSize); - const char* getFunctionName(transaction_code_t code) const; - size_t getTransactionCodeToFunctionLength() const { return mTransactionCodeToFunctionLength; } // whether a transaction header should be written bool writeHeader = true; @@ -154,10 +151,6 @@ struct AIBinder_Class { // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to // one. const ::android::String16 mWideInterfaceDescriptor; - // Array which holds names of the functions - const char** mTransactionCodeToFunction = nullptr; - // length of mmTransactionCodeToFunctionLength array - size_t mTransactionCodeToFunctionLength = 0; }; // Ownership is like this (when linked to death): 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 a6790912a7..af56bf0da1 100644 --- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h +++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h @@ -30,17 +30,6 @@ #include <android/binder_auto_utils.h> #include <android/binder_ibinder.h> -#if defined(__ANDROID_VENDOR__) -#include <android/llndk-versioning.h> -#elif !defined(API_LEVEL_AT_LEAST) -#if defined(__BIONIC__) -#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \ - (__builtin_available(android sdk_api_level, *)) -#else -#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) (true) -#endif // __BIONIC__ -#endif // __ANDROID_VENDOR__ - #if __has_include(<android/binder_shell.h>) #include <android/binder_shell.h> #define HAS_BINDER_SHELL_COMMAND @@ -175,8 +164,7 @@ class ICInterface : public SharedRefBase { * Helper method to create a class */ static inline AIBinder_Class* defineClass(const char* interfaceDescriptor, - AIBinder_Class_onTransact onTransact, - const char** codeToFunction, size_t functionCount); + AIBinder_Class_onTransact onTransact); private: class ICInterfaceData { @@ -267,8 +255,7 @@ std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) { } AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor, - AIBinder_Class_onTransact onTransact, - const char** codeToFunction, size_t functionCount) { + AIBinder_Class_onTransact onTransact) { AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate, ICInterfaceData::onDestroy, onTransact); if (clazz == nullptr) { @@ -287,15 +274,6 @@ AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor, AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand); } #endif - -#if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 36 - if API_LEVEL_AT_LEAST (36, 202504) { - AIBinder_Class_setTransactionCodeToFunctionNameMap(clazz, codeToFunction, functionCount); - } -#else - (void)codeToFunction; - (void)functionCount; -#endif // defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 36 return clazz; } diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index aaf4698446..72d255e816 100644 --- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h +++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h @@ -26,20 +26,14 @@ #pragma once -#include <android/binder_parcel.h> -#if defined(__ANDROID_VENDOR__) -#include <android/llndk-versioning.h> -#else -#if !defined(__INTRODUCED_IN_LLNDK) -#define __INTRODUCED_IN_LLNDK(level) __attribute__((annotate("introduced_in_llndk=" #level))) -#endif -#endif // __ANDROID_VENDOR__ -#include <android/binder_status.h> #include <stdbool.h> #include <stdint.h> #include <sys/cdefs.h> #include <sys/types.h> +#include <android/binder_parcel.h> +#include <android/binder_status.h> + __BEGIN_DECLS /** @@ -225,51 +219,6 @@ typedef binder_status_t (*AIBinder_onDump)(AIBinder* binder, int fd, const char* void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29); /** - * Associates a mapping of transaction codes(transaction_code_t) to function names for the given - * class. - * - * Trace messages will use the provided names instead of bare integer codes when set. If not set by - * this function, trace messages will only be identified by the bare code. This should be called one - * time during clazz initialization. clazz and transactionCodeToFunctionMap should have same - * lifetime. Resetting/clearing the transactionCodeToFunctionMap is not allowed. - * - * Available since API level 36. - * - * \param clazz class which should use this transaction to code function map. - * \param transactionCodeToFunctionMap array of function names indexed by transaction code. - * Transaction codes start from 1, functions with transaction code 1 will correspond to index 0 in - * transactionCodeToFunctionMap. When defining methods, transaction codes are expected to be - * contiguous, and this is required for maximum memory efficiency. - * You can use nullptr if certain transaction codes are not used. Lifetime should be same as clazz. - * \param length number of elements in the transactionCodeToFunctionMap - * - * \return true if setting codeToFunction to clazz is successful. return false if clazz or - * codeToFunction is nullptr. - */ -void AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class* clazz, - const char** transactionCodeToFunctionMap, - size_t length) __INTRODUCED_IN(36) - __INTRODUCED_IN_LLNDK(202504); - -/** - * Get function name associated with transaction code for given class - * - * This function returns function name associated with provided transaction code for given class. - * AIBinder_Class_setTransactionCodeToFunctionNameMap should be called first to associate function - * to transaction code mapping. - * - * Available since API level 36. - * - * \param clazz class for which function name is requested - * \param transactionCode transaction_code_t for which function name is requested. - * - * \return function name in form of const char* if transaction code is valid for given class. - * if transaction code is invalid or transactionCodeToFunctionMap is not set, nullptr is returned - */ -const char* AIBinder_Class_getFunctionName(AIBinder_Class* clazz, transaction_code_t code) - __INTRODUCED_IN(36) __INTRODUCED_IN_LLNDK(202504); - -/** * This tells users of this class not to use a transaction header. By default, libbinder_ndk users * read/write transaction headers implicitly (in the SDK, this must be manually written by * android.os.Parcel#writeInterfaceToken, and it is read/checked with diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index 800d83a2f9..826e199093 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -248,14 +248,6 @@ LIBBINDER_NDK35 { # introduced=VanillaIceCream AServiceManager_openDeclaredPassthroughHal; # systemapi llndk=202404 }; -LIBBINDER_NDK36 { # introduced=36 - global: - AIBinder_Class_setTransactionCodeToFunctionNameMap; - AIBinder_Class_setTransactionCodeToFunctionNameMap; # llndk=202504 - AIBinder_Class_getFunctionName; - AIBinder_Class_getFunctionName; # llndk=202504 -}; - LIBBINDER_NDK_PLATFORM { global: AParcel_getAllowFds; diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index e5a3da460e..3cd2b9a891 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -1108,37 +1108,6 @@ TEST(NdkBinder_ScopedAResource, Release) { EXPECT_EQ(deleteCount, 0); } -void* EmptyOnCreate(void* args) { - return args; -} -void EmptyOnDestroy(void* /*userData*/) {} -binder_status_t EmptyOnTransact(AIBinder* /*binder*/, transaction_code_t /*code*/, - const AParcel* /*in*/, AParcel* /*out*/) { - return STATUS_OK; -} - -TEST(NdkBinder_DeathTest, SetCodeMapTwice) { - const char* codeToFunction1[] = {"function-1", "function-2", "function-3"}; - const char* codeToFunction2[] = {"function-4", "function-5"}; - const char* interfaceName = "interface_descriptor"; - AIBinder_Class* clazz = - AIBinder_Class_define(interfaceName, EmptyOnCreate, EmptyOnDestroy, EmptyOnTransact); - AIBinder_Class_setTransactionCodeToFunctionNameMap(clazz, codeToFunction1, 3); - // Reset/clear is not allowed - EXPECT_DEATH(AIBinder_Class_setTransactionCodeToFunctionNameMap(clazz, codeToFunction2, 2), ""); -} - -TEST(NdkBinder_DeathTest, SetNullCodeMap) { - const char* codeToFunction[] = {"function-1", "function-2", "function-3"}; - const char* interfaceName = "interface_descriptor"; - AIBinder_Class* clazz = - AIBinder_Class_define(interfaceName, EmptyOnCreate, EmptyOnDestroy, EmptyOnTransact); - EXPECT_DEATH(AIBinder_Class_setTransactionCodeToFunctionNameMap(nullptr, codeToFunction, 3), - ""); - EXPECT_DEATH(AIBinder_Class_setTransactionCodeToFunctionNameMap(clazz, nullptr, 0), ""); - EXPECT_DEATH(AIBinder_Class_setTransactionCodeToFunctionNameMap(nullptr, nullptr, 0), ""); -} - int main(int argc, char* argv[]) { ::testing::InitGoogleTest(&argc, argv); diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp index e3a337171f..3a1471eabe 100644 --- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp @@ -49,8 +49,7 @@ static binder_status_t onTransact(AIBinder*, transaction_code_t, const AParcel*, return STATUS_UNKNOWN_TRANSACTION; } -static AIBinder_Class* g_class = - ::ndk::ICInterface::defineClass("ISomeInterface", onTransact, nullptr, 0); +static AIBinder_Class* g_class = ::ndk::ICInterface::defineClass("ISomeInterface", onTransact); class BpSomeInterface : public ::ndk::BpCInterface<ISomeInterface> { public: diff --git a/libs/binder/trusty/OS.cpp b/libs/binder/trusty/OS.cpp index ba9e457a75..157ab3c85d 100644 --- a/libs/binder/trusty/OS.cpp +++ b/libs/binder/trusty/OS.cpp @@ -42,10 +42,6 @@ void trace_end(uint64_t) {} void trace_int(uint64_t, const char*, int32_t) {} -uint64_t get_trace_enabled_tags() { - return 0; -} - uint64_t GetThreadId() { return 0; } diff --git a/libs/binder/trusty/ndk/include/android/llndk-versioning.h b/libs/binder/trusty/ndk/include/android/llndk-versioning.h index 91a4e9473a..3ae3d8f577 100644 --- a/libs/binder/trusty/ndk/include/android/llndk-versioning.h +++ b/libs/binder/trusty/ndk/include/android/llndk-versioning.h @@ -16,5 +16,3 @@ #pragma once #define __INTRODUCED_IN_LLNDK(x) /* nothing on Trusty */ - -#define API_LEVEL_AT_LEAST(x, y) (false) /* nothing on Trusty */ |