Define macros for LLNDK versioning
__INTRODUCED_IN_LLNDK(vendor_api_level) is for the LLNDK APIs
introduced in the vendor_api_level. It is ignored for non-vendor
modules.
API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) is used as a
statement for 'if' to guard the API callers. For example:
if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
new_api_for_V_and_202404();
} else {
fallback_function();
}
Bug: 302113279
Test: build trunk-staging and next configurations
Change-Id: I60d40655b1f8afdfa5c69b2ac4be2205f8057bea
diff --git a/libvendorsupport/include_llndk/android/llndk-versioning.h b/libvendorsupport/include_llndk/android/llndk-versioning.h
index b375a2f..b500149 100644
--- a/libvendorsupport/include_llndk/android/llndk-versioning.h
+++ b/libvendorsupport/include_llndk/android/llndk-versioning.h
@@ -32,18 +32,25 @@
"call with '#if (__ANDROID_VENDOR_API__ >= " #vendor_api_level ")'."))) \
_Pragma("clang diagnostic pop")
-// For the vendor libraries, __INTRODUCED_IN must be ignored because they are only for NDKs but not
-// for LLNDKs.
-#undef __INTRODUCED_IN
-#define __INTRODUCED_IN(x)
+// Use this macro as an `if` statement to call an API that are available to both NDK and LLNDK.
+// This returns true for the vendor modules if the vendor_api_level is less than or equal to the
+// ro.board.api_level.
+#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \
+ constexpr(__ANDROID_VENDOR_API__ >= vendor_api_level)
#else // __ANDROID_VENDOR__
-// For non-vendor libraries, __INTRODUCED_IN_LLNDK must be ignored because it must not change
-// symbols of NDK or the system side of the treble boundary. It leaves a no-op annotation for ABI
-// analysis.
+// __INTRODUCED_IN_LLNDK is for LLNDK only but not for NDK. Ignore this for non-vendor modules.
+// It leaves a no-op annotation for ABI analysis.
+#if !defined(__INTRODUCED_IN_LLNDK)
#define __INTRODUCED_IN_LLNDK(vendor_api_level) \
__attribute__((annotate("introduced_in_llndk=" #vendor_api_level)))
+#endif
+
+// For non-vendor modules, API_LEVEL_AT_LEAST is replaced with __builtin_available(sdk_api_level) to
+// guard the API for __INTRODUCED_IN.
+#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \
+ (__builtin_available(android sdk_api_level, *))
#endif // __ANDROID_VENDOR__