hiddenapi: add 'test-api' flag into dex files.

Only tests should have access to @TestApi signatures. But now all of them are greylisted, hence can be accessed by anyone. This should be changed so that grey/black/whitelist properties would be orthogonal to test-api.

The first step to fix this is to introduce extra flag and embed it into dex files. In the future access decisions will be made based on that flag.

Bug: 133832325
Test: make -j32 test-art-host-gtest-hiddenapi_test
Change-Id: I0db8938391d6aefe5e9a3bc51ec99b948ae41f6d
diff --git a/libartbase/base/hiddenapi_flags.h b/libartbase/base/hiddenapi_flags.h
index 59e17a8..e79e5f3 100644
--- a/libartbase/base/hiddenapi_flags.h
+++ b/libartbase/base/hiddenapi_flags.h
@@ -64,6 +64,13 @@
   // kMin and kMax and no integer values are skipped between them.
   template<typename T>
   constexpr uint32_t NumValues() { return ToUint(T::kMax) - ToUint(T::kMin) + 1; }
+
+  // Returns enum value at position i from enum list.
+  template <typename T>
+  constexpr T GetEnumAt(uint32_t i) {
+    return static_cast<T>(ToUint(T::kMin) + i);
+  }
+
 }  // namespace helper
 
 /*
@@ -101,10 +108,11 @@
   // These are used for domain-specific API.
   enum class DomainApi : uint32_t {
     kCorePlatformApi = kValueBitSize,
+    kTestApi = kValueBitSize + 1,
 
     // Special values
     kMin =             kCorePlatformApi,
-    kMax =             kCorePlatformApi,
+    kMax =             kTestApi,
   };
 
   // Bit mask of all domain API flags.
@@ -134,6 +142,7 @@
   // Names corresponding to DomainApis.
   static constexpr const char* kDomainApiNames[] {
     "core-platform-api",
+    "test-api",
   };
 
   // Maximum SDK versions allowed to access ApiList of given Value.
@@ -185,6 +194,7 @@
   static ApiList GreylistMaxO() { return ApiList(Value::kGreylistMaxO); }
   static ApiList GreylistMaxP() { return ApiList(Value::kGreylistMaxP); }
   static ApiList CorePlatformApi() { return ApiList(DomainApi::kCorePlatformApi); }
+  static ApiList TestApi() { return ApiList(DomainApi::kTestApi); }
 
   uint32_t GetDexFlags() const { return dex_flags_; }
   uint32_t GetIntValue() const { return helper::ToUint(GetValue()) - helper::ToUint(Value::kMin); }
@@ -193,12 +203,12 @@
   static ApiList FromName(const std::string& str) {
     for (uint32_t i = 0; i < kValueCount; ++i) {
       if (str == kValueNames[i]) {
-        return ApiList(static_cast<Value>(i + helper::ToUint(Value::kMin)));
+        return ApiList(helper::GetEnumAt<Value>(i));
       }
     }
     for (uint32_t i = 0; i < kDomainApiCount; ++i) {
       if (str == kDomainApiNames[i]) {
-        return ApiList(static_cast<DomainApi>(i + helper::ToUint(DomainApi::kMin)));
+        return ApiList(helper::GetEnumAt<DomainApi>(i));
       }
     }
     return ApiList();
@@ -290,14 +300,14 @@
     }
 
     const uint32_t domain_apis = GetDomainApis();
-    for (uint32_t i = helper::ToUint(DomainApi::kMin); i <= helper::ToUint(DomainApi::kMax); i++) {
-      if (helper::MatchesBitMask(helper::ToBit(i), domain_apis)) {
+    for (uint32_t i = 0; i < kDomainApiCount; i++) {
+      if (helper::MatchesBitMask(helper::ToBit(helper::GetEnumAt<DomainApi>(i)), domain_apis)) {
         if (is_first) {
           is_first = false;
         } else {
           os << ",";
         }
-        os << kDomainApiNames[i - helper::ToUint(DomainApi::kMin)];
+        os << kDomainApiNames[i];
       }
     }
 
@@ -306,6 +316,13 @@
 
   static constexpr uint32_t kValueCount = helper::NumValues<Value>();
   static constexpr uint32_t kDomainApiCount = helper::NumValues<DomainApi>();
+
+  // Check min and max values are calculated correctly.
+  static_assert(Value::kMin == helper::GetEnumAt<Value>(0));
+  static_assert(Value::kMax == helper::GetEnumAt<Value>(kValueCount - 1));
+
+  static_assert(DomainApi::kMin == helper::GetEnumAt<DomainApi>(0));
+  static_assert(DomainApi::kMax == helper::GetEnumAt<DomainApi>(kDomainApiCount - 1));
 };
 
 inline std::ostream& operator<<(std::ostream& os, ApiList value) {