Rename and reorganize hiddenapi::ApiList

Change values of ApiList flags to make them easier to extend in the
future and unify naming across all components. Light greylist is now
just "Greylist", dark greylist becomes "GreylistMaxO".

Note that the version code in "GreylistMaxO" must also include any
maintenance releases, i.e. entries on "GreylistMaxO" are accessible
to apps with targetSdkVersion<=27 (O MR1).

Test: m, phone boots
Test: m test-art
Change-Id: I9622e0646eb265008a8bb2652270876ae95dac84
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 09f0b20..32122eb 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -34,6 +34,7 @@
 #include "android-base/stringprintf.h"
 
 #include "base/logging.h"  // For VLOG_IS_ON.
+#include "base/hiddenapi_flags.h"
 #include "base/mem_map.h"
 #include "base/os.h"
 #include "base/utils.h"
@@ -222,15 +223,10 @@
   return str;
 }
 
-static const char* GetHiddenapiFlagStr(uint32_t hiddenapi_flags) {
-  static const char* const kValue[] = {
-    "WHITELIST",             /* 0x0 */
-    "LIGHT_GREYLIST",        /* 0x1 */
-    "DARK_GREYLIST",         /* 0x2 */
-    "BLACKLIST",             /* 0x3 */
-  };
-  DCHECK_LT(hiddenapi_flags, arraysize(kValue));
-  return kValue[hiddenapi_flags];
+static std::string GetHiddenapiFlagStr(uint32_t hiddenapi_flags) {
+  std::string api_list(hiddenapi::ApiList::FromDexFlags(hiddenapi_flags).GetName());
+  std::transform(api_list.begin(), api_list.end(), api_list.begin(), ::toupper);
+  return api_list;
 }
 
 static std::string GetSignatureForProtoId(const dex_ir::ProtoId* proto) {
@@ -1173,7 +1169,6 @@
   char* type_descriptor = strdup(GetSignatureForProtoId(method_id->Proto()).c_str());
   const char* back_descriptor = method_id->Class()->GetStringId()->Data();
   char* access_str = CreateAccessFlagStr(flags, kAccessForMethod);
-  const char* hiddenapi_str = GetHiddenapiFlagStr(hiddenapi_flags);
 
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "    #%d              : (in %s)\n", i, back_descriptor);
@@ -1181,7 +1176,10 @@
     fprintf(out_file_, "      type          : '%s'\n", type_descriptor);
     fprintf(out_file_, "      access        : 0x%04x (%s)\n", flags, access_str);
     if (hiddenapi_flags != 0u) {
-      fprintf(out_file_, "      hiddenapi     : 0x%04x (%s)\n", hiddenapi_flags, hiddenapi_str);
+      fprintf(out_file_,
+              "      hiddenapi     : 0x%04x (%s)\n",
+              hiddenapi_flags,
+              GetHiddenapiFlagStr(hiddenapi_flags).c_str());
     }
     if (code == nullptr) {
       fprintf(out_file_, "      code          : (none)\n");
@@ -1291,7 +1289,6 @@
   const char* type_descriptor = field_id->Type()->GetStringId()->Data();
   const char* back_descriptor = field_id->Class()->GetStringId()->Data();
   char* access_str = CreateAccessFlagStr(flags, kAccessForField);
-  const char* hiddenapi_str = GetHiddenapiFlagStr(hiddenapi_flags);
 
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "    #%d              : (in %s)\n", i, back_descriptor);
@@ -1299,7 +1296,10 @@
     fprintf(out_file_, "      type          : '%s'\n", type_descriptor);
     fprintf(out_file_, "      access        : 0x%04x (%s)\n", flags, access_str);
     if (hiddenapi_flags != 0u) {
-      fprintf(out_file_, "      hiddenapi     : 0x%04x (%s)\n", hiddenapi_flags, hiddenapi_str);
+      fprintf(out_file_,
+              "      hiddenapi     : 0x%04x (%s)\n",
+              hiddenapi_flags,
+              GetHiddenapiFlagStr(hiddenapi_flags).c_str());
     }
     if (init != nullptr) {
       fputs("      value         : ", out_file_);
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index 6a667bc..58d12a1 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -27,6 +27,7 @@
         "base/file_magic.cc",
         "base/file_utils.cc",
         "base/hex_dump.cc",
+        "base/hiddenapi_flags.cc",
         "base/logging.cc",
         "base/malloc_arena_pool.cc",
         "base/membarrier.cc",
diff --git a/libartbase/base/hiddenapi_flags.cc b/libartbase/base/hiddenapi_flags.cc
new file mode 100644
index 0000000..6caa75c
--- /dev/null
+++ b/libartbase/base/hiddenapi_flags.cc
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "hiddenapi_flags.h"
+
+namespace art {
+namespace hiddenapi {
+
+constexpr const char* ApiList::kNames[ApiList::kValueCount];
+constexpr SdkVersion ApiList::kMaxSdkVersions[ApiList::kValueCount];
+
+}  // namespace hiddenapi
+}  // namespace art
diff --git a/libartbase/base/hiddenapi_flags.h b/libartbase/base/hiddenapi_flags.h
new file mode 100644
index 0000000..8e7269c
--- /dev/null
+++ b/libartbase/base/hiddenapi_flags.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef ART_LIBARTBASE_BASE_HIDDENAPI_FLAGS_H_
+#define ART_LIBARTBASE_BASE_HIDDENAPI_FLAGS_H_
+
+#include "sdk_version.h"
+
+#include "android-base/logging.h"
+
+namespace art {
+namespace hiddenapi {
+
+/*
+ * This class represents the information whether a field/method is in
+ * public API (whitelist) or if it isn't, apps targeting which SDK
+ * versions are allowed to access it.
+ */
+class ApiList {
+ private:
+  using IntValueType = uint32_t;
+
+  enum class Value : IntValueType {
+    // Values independent of target SDK version of app
+    kWhitelist =     0,
+    kGreylist =      1,
+    kBlacklist =     2,
+
+    // Values dependent on target SDK version of app. Put these last as
+    // their list will be extended in future releases.
+    // The max release code implicitly includes all maintenance releases,
+    // e.g. GreylistMaxO is accessible to targetSdkVersion <= 27 (O_MR1).
+    kGreylistMaxO =  3,
+
+    // Special values
+    kInvalid =       static_cast<uint32_t>(-1),
+    kMinValue =      kWhitelist,
+    kMaxValue =      kGreylistMaxO,
+  };
+
+  static constexpr const char* kNames[] = {
+    "whitelist",
+    "greylist",
+    "blacklist",
+    "greylist-max-o",
+  };
+
+  static constexpr SdkVersion kMaxSdkVersions[] {
+    /* whitelist */ SdkVersion::kMax,
+    /* greylist */ SdkVersion::kMax,
+    /* blacklist */ SdkVersion::kMin,
+    /* greylist-max-o */ SdkVersion::kO_MR1,
+  };
+
+  static ApiList MinValue() { return ApiList(Value::kMinValue); }
+  static ApiList MaxValue() { return ApiList(Value::kMaxValue); }
+
+  explicit ApiList(Value value) : value_(value) {}
+
+  const Value value_;
+
+ public:
+  static ApiList Whitelist() { return ApiList(Value::kWhitelist); }
+  static ApiList Greylist() { return ApiList(Value::kGreylist); }
+  static ApiList Blacklist() { return ApiList(Value::kBlacklist); }
+  static ApiList GreylistMaxO() { return ApiList(Value::kGreylistMaxO); }
+  static ApiList Invalid() { return ApiList(Value::kInvalid); }
+
+  // Decodes ApiList from dex hiddenapi flags.
+  static ApiList FromDexFlags(uint32_t dex_flags) {
+    if (MinValue().GetIntValue() <= dex_flags && dex_flags <= MaxValue().GetIntValue()) {
+      return ApiList(static_cast<Value>(dex_flags));
+    }
+    return Invalid();
+  }
+
+  // Returns the ApiList with a given name.
+  static ApiList FromName(const std::string& str) {
+    for (IntValueType i = MinValue().GetIntValue(); i <= MaxValue().GetIntValue(); i++) {
+      ApiList current = ApiList(static_cast<Value>(i));
+      if (str == current.GetName()) {
+        return current;
+      }
+    }
+    return Invalid();
+  }
+
+  bool operator==(const ApiList other) const { return value_ == other.value_; }
+  bool operator!=(const ApiList other) const { return !(*this == other); }
+
+  bool IsValid() const { return *this != Invalid(); }
+
+  IntValueType GetIntValue() const {
+    DCHECK(IsValid());
+    return static_cast<IntValueType>(value_);
+  }
+
+  const char* GetName() const { return kNames[GetIntValue()]; }
+
+  SdkVersion GetMaxAllowedSdkVersion() const { return kMaxSdkVersions[GetIntValue()]; }
+
+  static constexpr size_t kValueCount = static_cast<size_t>(Value::kMaxValue) + 1;
+};
+
+inline std::ostream& operator<<(std::ostream& os, ApiList value) {
+  os << value.GetName();
+  return os;
+}
+
+inline bool AreValidDexFlags(uint32_t dex_flags) {
+  return ApiList::FromDexFlags(dex_flags).IsValid();
+}
+
+}  // namespace hiddenapi
+}  // namespace art
+
+
+#endif  // ART_LIBARTBASE_BASE_HIDDENAPI_FLAGS_H_
diff --git a/libdexfile/dex/class_accessor-inl.h b/libdexfile/dex/class_accessor-inl.h
index e9e3a98..f0f14c6 100644
--- a/libdexfile/dex/class_accessor-inl.h
+++ b/libdexfile/dex/class_accessor-inl.h
@@ -19,6 +19,7 @@
 
 #include "class_accessor.h"
 
+#include "base/hiddenapi_flags.h"
 #include "base/leb128.h"
 #include "class_iterator.h"
 #include "code_item_accessors-inl.h"
@@ -65,7 +66,7 @@
   code_off_ = DecodeUnsignedLeb128(&ptr_pos_);
   if (hiddenapi_ptr_pos_ != nullptr) {
     hiddenapi_flags_ = DecodeUnsignedLeb128(&hiddenapi_ptr_pos_);
-    DCHECK(hiddenapi::AreValidFlags(hiddenapi_flags_));
+    DCHECK(hiddenapi::AreValidDexFlags(hiddenapi_flags_));
   }
 }
 
@@ -74,7 +75,7 @@
   access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
   if (hiddenapi_ptr_pos_ != nullptr) {
     hiddenapi_flags_ = DecodeUnsignedLeb128(&hiddenapi_ptr_pos_);
-    DCHECK(hiddenapi::AreValidFlags(hiddenapi_flags_));
+    DCHECK(hiddenapi::AreValidDexFlags(hiddenapi_flags_));
   }
 }
 
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index b3e7ad4..83f47fe 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -29,7 +29,6 @@
 #include "base/value_object.h"
 #include "class_iterator.h"
 #include "dex_file_types.h"
-#include "hidden_api_access_flags.h"
 #include "jni.h"
 #include "modifiers.h"
 
diff --git a/libdexfile/dex/dex_file_layout.cc b/libdexfile/dex/dex_file_layout.cc
index 1e36e05..75a3111 100644
--- a/libdexfile/dex/dex_file_layout.cc
+++ b/libdexfile/dex/dex_file_layout.cc
@@ -18,6 +18,7 @@
 
 #include <sys/mman.h>
 
+#include "base/bit_utils.h"
 #include "dex_file.h"
 
 namespace art {
diff --git a/libdexfile/dex/dex_file_verifier.cc b/libdexfile/dex/dex_file_verifier.cc
index 4d33cd5..78e4618 100644
--- a/libdexfile/dex/dex_file_verifier.cc
+++ b/libdexfile/dex/dex_file_verifier.cc
@@ -1632,7 +1632,7 @@
         failure = true;
         return;
       }
-      if (!hiddenapi::AreValidFlags(decoded_flags)) {
+      if (!hiddenapi::AreValidDexFlags(decoded_flags)) {
         ErrorStringPrintf("Hiddenapi class data flags invalid (%u) for %s %i",
                           decoded_flags, member_type, member.GetIndex());
         failure = true;
diff --git a/libdexfile/dex/hidden_api_access_flags.h b/libdexfile/dex/hidden_api_access_flags.h
deleted file mode 100644
index 77bfbc9..0000000
--- a/libdexfile/dex/hidden_api_access_flags.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef ART_LIBDEXFILE_DEX_HIDDEN_API_ACCESS_FLAGS_H_
-#define ART_LIBDEXFILE_DEX_HIDDEN_API_ACCESS_FLAGS_H_
-
-#include "base/bit_utils.h"
-#include "base/macros.h"
-#include "dex/modifiers.h"
-
-/* This class is used for encoding and decoding access flags of class members
- * from the boot class path. These access flags might contain additional two bits
- * of information on whether the given class member should be hidden from apps
- * and under what circumstances.
- *
- * Two bits are encoded for each class member in the HiddenapiClassData item,
- * stored in a stream of uleb128-encoded values for each ClassDef item.
- * The two bits correspond to values in the ApiList enum below.
- *
- * At runtime, two bits are set aside in the uint32_t access flags in the
- * intrinsics ordinal space (thus intrinsics need to be special-cased). These are
- * two consecutive bits and they are directly used to store the integer value of
- * the ApiList enum values.
- *
- */
-
-namespace art {
-namespace hiddenapi {
-
-enum class ApiList {
-  kWhitelist = 0,
-  kLightGreylist,
-  kDarkGreylist,
-  kBlacklist,
-  kNoList,
-};
-
-inline bool AreValidFlags(uint32_t flags) {
-  return flags <= static_cast<uint32_t>(ApiList::kBlacklist);
-}
-
-inline std::ostream& operator<<(std::ostream& os, ApiList value) {
-  switch (value) {
-    case ApiList::kWhitelist:
-      os << "whitelist";
-      break;
-    case ApiList::kLightGreylist:
-      os << "light greylist";
-      break;
-    case ApiList::kDarkGreylist:
-      os << "dark greylist";
-      break;
-    case ApiList::kBlacklist:
-      os << "blacklist";
-      break;
-    case ApiList::kNoList:
-      os << "no list";
-      break;
-  }
-  return os;
-}
-
-}  // namespace hiddenapi
-}  // namespace art
-
-
-#endif  // ART_LIBDEXFILE_DEX_HIDDEN_API_ACCESS_FLAGS_H_
diff --git a/libdexfile/dex/test_dex_file_builder.h b/libdexfile/dex/test_dex_file_builder.h
index 2d8a0bb..072aafb 100644
--- a/libdexfile/dex/test_dex_file_builder.h
+++ b/libdexfile/dex/test_dex_file_builder.h
@@ -26,6 +26,7 @@
 
 #include <android-base/logging.h>
 
+#include "base/bit_utils.h"
 #include "dex/dex_file_loader.h"
 #include "dex/standard_dex_file.h"
 
diff --git a/runtime/art_field.h b/runtime/art_field.h
index 1cf7afa..0a4aa7e 100644
--- a/runtime/art_field.h
+++ b/runtime/art_field.h
@@ -20,7 +20,6 @@
 #include <jni.h>
 
 #include "dex/dex_file_types.h"
-#include "dex/hidden_api_access_flags.h"
 #include "dex/modifiers.h"
 #include "dex/primitive.h"
 #include "gc_root.h"
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index 188c5f3..d3df7fd 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -21,7 +21,6 @@
 #include "art_field-inl.h"
 #include "art_method-inl.h"
 #include "base/dumpable.h"
-#include "base/sdk_version.h"
 #include "dex/class_accessor-inl.h"
 #include "scoped_thread_state_change.h"
 #include "thread-inl.h"
@@ -76,21 +75,6 @@
   kAccessDenied  = 1 << 1,
 };
 
-static SdkVersion GetMaxAllowedSdkVersionForApiList(ApiList api_list) {
-  switch (api_list) {
-    case ApiList::kWhitelist:
-    case ApiList::kLightGreylist:
-      return SdkVersion::kMax;
-    case ApiList::kDarkGreylist:
-      return SdkVersion::kO_MR1;
-    case ApiList::kBlacklist:
-      return SdkVersion::kMin;
-    case ApiList::kNoList:
-      LOG(FATAL) << "Unexpected value";
-      UNREACHABLE();
-  }
-}
-
 MemberSignature::MemberSignature(ArtField* field) {
   class_name_ = field->GetDeclaringClass()->GetDescriptor(&tmp_);
   member_name_ = field->GetName();
@@ -264,7 +248,7 @@
   }
 
   uint32_t flags = kInvalidDexFlags;
-  DCHECK(!AreValidFlags(flags));
+  DCHECK(!AreValidDexFlags(flags));
 
   ClassAccessor accessor(declaring_class->GetDexFile(),
                          *class_def,
@@ -277,7 +261,7 @@
   accessor.VisitFields(fn_visit, fn_visit);
 
   CHECK_NE(flags, kInvalidDexFlags) << "Could not find flags for field " << field->PrettyField();
-  DCHECK(AreValidFlags(flags));
+  DCHECK(AreValidDexFlags(flags));
   return flags;
 }
 
@@ -294,7 +278,7 @@
   }
 
   uint32_t flags = kInvalidDexFlags;
-  DCHECK(!AreValidFlags(flags));
+  DCHECK(!AreValidDexFlags(flags));
 
   ClassAccessor accessor(declaring_class->GetDexFile(),
                          *class_def,
@@ -307,7 +291,7 @@
   accessor.VisitMethods(fn_visit, fn_visit);
 
   CHECK_NE(flags, kInvalidDexFlags) << "Could not find flags for method " << method->PrettyMethod();
-  DCHECK(AreValidFlags(flags));
+  DCHECK(AreValidDexFlags(flags));
   return flags;
 }
 
@@ -323,7 +307,7 @@
   const bool deny_access =
       (policy == EnforcementPolicy::kEnabled) &&
       IsSdkVersionSetAndMoreThan(runtime->GetTargetSdkVersion(),
-                                 GetMaxAllowedSdkVersionForApiList(api_list));
+                                 api_list.GetMaxAllowedSdkVersion());
 
   MemberSignature member_signature(member);
 
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index 32bae11..eea58e9 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -19,8 +19,8 @@
 
 #include "art_field.h"
 #include "art_method.h"
+#include "base/hiddenapi_flags.h"
 #include "base/mutex.h"
-#include "dex/hidden_api_access_flags.h"
 #include "intrinsics_enum.h"
 #include "mirror/class-inl.h"
 #include "reflection.h"
@@ -177,10 +177,10 @@
   uint32_t runtime_flags = 0u;
 
   uint32_t dex_flags = member.GetHiddenapiFlags();
-  DCHECK(AreValidFlags(dex_flags));
+  DCHECK(AreValidDexFlags(dex_flags));
 
-  ApiList api_list = static_cast<hiddenapi::ApiList>(dex_flags);
-  if (api_list == ApiList::kWhitelist) {
+  ApiList api_list = ApiList::FromDexFlags(dex_flags);
+  if (api_list == ApiList::Whitelist()) {
     runtime_flags |= kAccPublicApi;
   }
 
@@ -316,7 +316,7 @@
   // Decode hidden API access flags from the dex file.
   // This is an O(N) operation scaling with the number of fields/methods
   // in the class. Only do this on slow path and only do it once.
-  ApiList api_list = static_cast<hiddenapi::ApiList>(detail::GetDexFlags(member));
+  ApiList api_list = ApiList::FromDexFlags(detail::GetDexFlags(member));
 
   // Member is hidden and caller is not exempted. Enter slow path.
   return detail::ShouldDenyAccessToMemberImpl(member, api_list, access_method);
diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc
index 314d878..520dc6d 100644
--- a/runtime/hidden_api_test.cc
+++ b/runtime/hidden_api_test.cc
@@ -101,30 +101,32 @@
   ScopedObjectAccess soa(self_);
 
   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDisabled);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kWhitelist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kLightGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kDarkGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kBlacklist), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
 
   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kWhitelist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kLightGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kDarkGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kBlacklist), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
 
   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
-  runtime_->SetTargetSdkVersion(static_cast<uint32_t>(SdkVersion::kO_MR1));
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kWhitelist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kLightGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kDarkGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kBlacklist), true);
+  runtime_->SetTargetSdkVersion(
+      static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()));
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
 
   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
-  runtime_->SetTargetSdkVersion(static_cast<uint32_t>(SdkVersion::kP));
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kWhitelist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kLightGreylist), false);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kDarkGreylist), true);
-  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::kBlacklist), true);
+  runtime_->SetTargetSdkVersion(
+      static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()) + 1);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
+  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
 }
 
 TEST_F(HiddenApiTest, CheckMembersRead) {
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index bd59e73..f24711a 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -31,7 +31,6 @@
 #include "dex/class_accessor-inl.h"
 #include "dex/dex_file.h"
 #include "dex/dex_file_loader.h"
-#include "dex/hidden_api_access_flags.h"
 #include "dex_to_dex_decompiler.h"
 #include "quicken_info.h"
 
diff --git a/test/674-hiddenapi/hiddenapi.cc b/test/674-hiddenapi/hiddenapi.cc
index d11aa57..2464263 100644
--- a/test/674-hiddenapi/hiddenapi.cc
+++ b/test/674-hiddenapi/hiddenapi.cc
@@ -30,7 +30,8 @@
 extern "C" JNIEXPORT void JNICALL Java_Main_init(JNIEnv*, jclass) {
   Runtime* runtime = Runtime::Current();
   runtime->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
-  runtime->SetTargetSdkVersion(static_cast<uint32_t>(SdkVersion::kO_MR1));
+  runtime->SetTargetSdkVersion(
+      static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()));
   runtime->SetDedupeHiddenApiWarnings(false);
 }
 
diff --git a/tools/hiddenapi/hiddenapi.cc b/tools/hiddenapi/hiddenapi.cc
index 2f016e9..7f4c546 100644
--- a/tools/hiddenapi/hiddenapi.cc
+++ b/tools/hiddenapi/hiddenapi.cc
@@ -23,14 +23,14 @@
 #include "android-base/strings.h"
 
 #include "base/bit_utils.h"
-#include "base/stl_util.h"
+#include "base/hiddenapi_flags.h"
 #include "base/mem_map.h"
 #include "base/os.h"
+#include "base/stl_util.h"
 #include "base/unix_file/fd_file.h"
 #include "dex/art_dex_file_loader.h"
 #include "dex/class_accessor-inl.h"
 #include "dex/dex_file-inl.h"
-#include "dex/hidden_api_access_flags.h"
 
 namespace art {
 
@@ -601,7 +601,7 @@
   // between BeginClassDef and EndClassDef in the order of appearance of
   // fields/methods in the class data stream.
   void WriteFlags(hiddenapi::ApiList flags) {
-    uint32_t uint_flags = static_cast<uint32_t>(flags);
+    uint32_t uint_flags = flags.GetIntValue();
     EncodeUnsignedLeb128(&data_, uint_flags);
     class_def_has_non_zero_flags_ |= (uint_flags != 0u);
   }
@@ -935,9 +935,9 @@
 
     // Load dex signatures.
     std::map<std::string, hiddenapi::ApiList> api_list;
-    OpenApiFile(light_greylist_path_, api_list, hiddenapi::ApiList::kLightGreylist);
-    OpenApiFile(dark_greylist_path_, api_list, hiddenapi::ApiList::kDarkGreylist);
-    OpenApiFile(blacklist_path_, api_list, hiddenapi::ApiList::kBlacklist);
+    OpenApiFile(light_greylist_path_, api_list, hiddenapi::ApiList::Greylist());
+    OpenApiFile(dark_greylist_path_, api_list, hiddenapi::ApiList::GreylistMaxO());
+    OpenApiFile(blacklist_path_, api_list, hiddenapi::ApiList::Blacklist());
 
     // Iterate over input dex files and insert HiddenapiClassData sections.
     for (size_t i = 0; i < boot_dex_paths_.size(); ++i) {
@@ -957,7 +957,7 @@
             // TODO: Load whitelist and CHECK that entry was found.
             auto it = api_list.find(boot_member.GetApiEntry());
             builder.WriteFlags(
-                (it == api_list.end()) ? hiddenapi::ApiList::kWhitelist : it->second);
+                (it == api_list.end()) ? hiddenapi::ApiList::Whitelist() : it->second);
           };
           auto fn_field = [&](const ClassAccessor::Field& boot_field) {
             fn_shared(DexMember(boot_class, boot_field));
@@ -988,7 +988,8 @@
 
     for (std::string line; std::getline(api_file, line);) {
       CHECK(api_list.find(line) == api_list.end())
-          << "Duplicate entry: " << line << " (" << api_list[line] << " and " << membership << ")";
+          << "Duplicate entry: " << line << " (" << api_list.find(line)->second
+          << " and " << membership << ")";
       api_list.emplace(line, membership);
     }
     api_file.close();
diff --git a/tools/hiddenapi/hiddenapi_test.cc b/tools/hiddenapi/hiddenapi_test.cc
index 0010b784..66ce2de 100644
--- a/tools/hiddenapi/hiddenapi_test.cc
+++ b/tools/hiddenapi/hiddenapi_test.cc
@@ -132,7 +132,7 @@
     CHECK(accessor.HasClassData()) << "Class " << accessor.GetDescriptor() << " has no data";
 
     if (!accessor.HasHiddenapiClassData()) {
-      return hiddenapi::ApiList::kWhitelist;
+      return hiddenapi::ApiList::Whitelist();
     }
 
     for (const ClassAccessor::Field& field : accessor.GetFields()) {
@@ -141,7 +141,7 @@
         const uint32_t actual_visibility = field.GetAccessFlags() & kAccVisibilityFlags;
         CHECK_EQ(actual_visibility, expected_visibility)
             << "Field " << name << " in class " << accessor.GetDescriptor();
-        return static_cast<hiddenapi::ApiList>(field.GetHiddenapiFlags());
+        return hiddenapi::ApiList::FromDexFlags(field.GetHiddenapiFlags());
       }
     }
 
@@ -159,7 +159,7 @@
     CHECK(accessor.HasClassData()) << "Class " << accessor.GetDescriptor() << " has no data";
 
     if (!accessor.HasHiddenapiClassData()) {
-      return hiddenapi::ApiList::kWhitelist;
+      return hiddenapi::ApiList::Whitelist();
     }
 
     for (const ClassAccessor::Method& method : accessor.GetMethods()) {
@@ -170,7 +170,7 @@
         const uint32_t actual_visibility = method.GetAccessFlags() & kAccVisibilityFlags;
         CHECK_EQ(actual_visibility, expected_visibility)
             << "Method " << name << " in class " << accessor.GetDescriptor();
-        return static_cast<hiddenapi::ApiList>(method.GetHiddenapiFlags());
+        return hiddenapi::ApiList::FromDexFlags(method.GetHiddenapiFlags());
       }
     }
 
@@ -224,7 +224,7 @@
   OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kWhitelist, GetIFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetIFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceFieldLightGreylistMatch) {
@@ -234,7 +234,7 @@
   OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kLightGreylist, GetIFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetIFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceFieldDarkGreylistMatch) {
@@ -244,7 +244,7 @@
   OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kDarkGreylist, GetIFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetIFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceFieldBlacklistMatch) {
@@ -254,7 +254,7 @@
   OpenStream(blacklist) << "LMain;->ifield:I" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kBlacklist, GetIFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetIFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch1) {
@@ -291,7 +291,7 @@
   OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kWhitelist, GetSFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetSFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticFieldLightGreylistMatch) {
@@ -301,7 +301,7 @@
   OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kLightGreylist, GetSFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetSFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticFieldDarkGreylistMatch) {
@@ -311,7 +311,7 @@
   OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kDarkGreylist, GetSFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetSFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticFieldBlacklistMatch) {
@@ -321,7 +321,7 @@
   OpenStream(blacklist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kBlacklist, GetSFieldHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetSFieldHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticFieldTwoListsMatch1) {
@@ -358,7 +358,7 @@
   OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kWhitelist, GetIMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetIMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceMethodLightGreylistMatch) {
@@ -368,7 +368,7 @@
   OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kLightGreylist, GetIMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetIMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceMethodDarkGreylistMatch) {
@@ -378,7 +378,7 @@
   OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kDarkGreylist, GetIMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetIMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceMethodBlacklistMatch) {
@@ -388,7 +388,7 @@
   OpenStream(blacklist) << "LMain;->imethod(J)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kBlacklist, GetIMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetIMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch1) {
@@ -425,7 +425,7 @@
   OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kWhitelist, GetSMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetSMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticMethodLightGreylistMatch) {
@@ -435,7 +435,7 @@
   OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kLightGreylist, GetSMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetSMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticMethodDarkGreylistMatch) {
@@ -445,7 +445,7 @@
   OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kDarkGreylist, GetSMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetSMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticMethodBlacklistMatch) {
@@ -455,7 +455,7 @@
   OpenStream(blacklist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kBlacklist, GetSMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetSMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticMethodTwoListsMatch1) {
@@ -492,7 +492,7 @@
   OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kWhitelist, GetINMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetINMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceNativeMethodLightGreylistMatch) {
@@ -502,7 +502,7 @@
   OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kLightGreylist, GetINMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetINMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceNativeMethodDarkGreylistMatch) {
@@ -512,7 +512,7 @@
   OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kDarkGreylist, GetINMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetINMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceNativeMethodBlacklistMatch) {
@@ -522,7 +522,7 @@
   OpenStream(blacklist) << "LMain;->inmethod(C)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kBlacklist, GetINMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetINMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch1) {
@@ -559,7 +559,7 @@
   OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kWhitelist, GetSNMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetSNMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticNativeMethodLightGreylistMatch) {
@@ -569,7 +569,7 @@
   OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kLightGreylist, GetSNMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetSNMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticNativeMethodDarkGreylistMatch) {
@@ -579,7 +579,7 @@
   OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kDarkGreylist, GetSNMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetSNMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticNativeMethodBlacklistMatch) {
@@ -589,7 +589,7 @@
   OpenStream(blacklist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
   auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
   ASSERT_NE(dex_file.get(), nullptr);
-  ASSERT_EQ(hiddenapi::ApiList::kBlacklist, GetSNMethodHiddenFlags(*dex_file));
+  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetSNMethodHiddenFlags(*dex_file));
 }
 
 TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch1) {
diff --git a/tools/veridex/hidden_api.h b/tools/veridex/hidden_api.h
index da9f058..b58332b 100644
--- a/tools/veridex/hidden_api.h
+++ b/tools/veridex/hidden_api.h
@@ -17,7 +17,7 @@
 #ifndef ART_TOOLS_VERIDEX_HIDDEN_API_H_
 #define ART_TOOLS_VERIDEX_HIDDEN_API_H_
 
-#include "dex/hidden_api_access_flags.h"
+#include "base/hiddenapi_flags.h"
 #include "dex/method_reference.h"
 
 #include <ostream>
@@ -45,20 +45,20 @@
 
   hiddenapi::ApiList GetApiList(const std::string& name) const {
     if (IsInList(name, blacklist_)) {
-      return hiddenapi::ApiList::kBlacklist;
+      return hiddenapi::ApiList::Blacklist();
     } else if (IsInList(name, dark_greylist_)) {
-      return hiddenapi::ApiList::kDarkGreylist;
+      return hiddenapi::ApiList::GreylistMaxO();
     } else if (IsInList(name, light_greylist_)) {
-      return hiddenapi::ApiList::kLightGreylist;
+      return hiddenapi::ApiList::Greylist();
     } else if (IsInList(name, whitelist_)) {
-      return hiddenapi::ApiList::kWhitelist;
+      return hiddenapi::ApiList::Whitelist();
     } else {
-      return hiddenapi::ApiList::kNoList;
+      return hiddenapi::ApiList::Invalid();
     }
   }
 
   bool IsInAnyList(const std::string& name) const {
-    return GetApiList(name) != hiddenapi::ApiList::kNoList;
+    return GetApiList(name).IsValid();
   }
 
   static std::string GetApiMethodName(const DexFile& dex_file, uint32_t method_index);
@@ -92,7 +92,7 @@
   uint32_t count = 0;
   uint32_t reflection_count = 0;
   uint32_t linking_count = 0;
-  uint32_t api_counts[5] = { 0, 0, 0, 0, 0 };
+  uint32_t api_counts[hiddenapi::ApiList::kValueCount] = {};  // initialize all to zero
 };
 
 }  // namespace art
diff --git a/tools/veridex/hidden_api_finder.cc b/tools/veridex/hidden_api_finder.cc
index e24d151..3cd7c95 100644
--- a/tools/veridex/hidden_api_finder.cc
+++ b/tools/veridex/hidden_api_finder.cc
@@ -180,7 +180,7 @@
   for (const std::pair<const std::string,
                        std::vector<MethodReference>>& pair : method_locations_) {
     hiddenapi::ApiList api_list = hidden_api_.GetApiList(pair.first);
-    stats->api_counts[static_cast<unsigned>(api_list)]++;
+    stats->api_counts[api_list.GetIntValue()]++;
     os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";
     os << std::endl;
     HiddenApiFinder::DumpReferences(os, pair.second);
@@ -191,7 +191,7 @@
   for (const std::pair<const std::string,
                        std::vector<MethodReference>>& pair : field_locations_) {
     hiddenapi::ApiList api_list = hidden_api_.GetApiList(pair.first);
-    stats->api_counts[static_cast<unsigned>(api_list)]++;
+    stats->api_counts[api_list.GetIntValue()]++;
     os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";
     os << std::endl;
     HiddenApiFinder::DumpReferences(os, pair.second);
@@ -204,8 +204,8 @@
       for (const std::string& name : strings_) {
         std::string full_name = cls + "->" + name;
         hiddenapi::ApiList api_list = hidden_api_.GetApiList(full_name);
-        stats->api_counts[static_cast<unsigned>(api_list)]++;
-        if (api_list != hiddenapi::ApiList::kNoList) {
+        if (api_list.IsValid()) {
+          stats->api_counts[api_list.GetIntValue()]++;
           stats->reflection_count++;
           os << "#" << ++stats->count << ": Reflection " << api_list << " " << full_name
              << " potential use(s):";
diff --git a/tools/veridex/precise_hidden_api_finder.cc b/tools/veridex/precise_hidden_api_finder.cc
index 6aef89f..be99ed2 100644
--- a/tools/veridex/precise_hidden_api_finder.cc
+++ b/tools/veridex/precise_hidden_api_finder.cc
@@ -91,8 +91,7 @@
       std::string cls(info.cls.ToString());
       std::string name(info.name.ToString());
       std::string full_name = cls + "->" + name;
-      hiddenapi::ApiList api_list = hidden_api_.GetApiList(full_name);
-      if (api_list != hiddenapi::ApiList::kNoList) {
+      if (hidden_api_.IsInAnyList(full_name)) {
         named_uses[full_name].push_back(ref);
       }
     }
@@ -102,7 +101,7 @@
     ++stats->reflection_count;
     const std::string& full_name = it.first;
     hiddenapi::ApiList api_list = hidden_api_.GetApiList(full_name);
-    stats->api_counts[static_cast<unsigned>(api_list)]++;
+    stats->api_counts[api_list.GetIntValue()]++;
     os << "#" << ++stats->count << ": Reflection " << api_list << " " << full_name << " use(s):";
     os << std::endl;
     for (const MethodReference& ref : it.second) {
diff --git a/tools/veridex/veridex.cc b/tools/veridex/veridex.cc
index 179e391..2787950 100644
--- a/tools/veridex/veridex.cc
+++ b/tools/veridex/veridex.cc
@@ -271,17 +271,17 @@
                                const VeridexOptions& options) {
     static const char* kPrefix = "       ";
     if (options.only_report_sdk_uses) {
-      os << stats.api_counts[static_cast<unsigned>(hiddenapi::ApiList::kWhitelist)]
+      os << stats.api_counts[hiddenapi::ApiList::Whitelist().GetIntValue()]
          << " SDK API uses." << std::endl;
     } else {
       os << stats.count << " hidden API(s) used: "
          << stats.linking_count << " linked against, "
          << stats.reflection_count << " through reflection" << std::endl;
-      os << kPrefix << stats.api_counts[static_cast<unsigned>(hiddenapi::ApiList::kBlacklist)]
+      os << kPrefix << stats.api_counts[hiddenapi::ApiList::Blacklist().GetIntValue()]
          << " in blacklist" << std::endl;
-      os << kPrefix << stats.api_counts[static_cast<unsigned>(hiddenapi::ApiList::kDarkGreylist)]
+      os << kPrefix << stats.api_counts[hiddenapi::ApiList::GreylistMaxO().GetIntValue()]
          << " in dark greylist" << std::endl;
-      os << kPrefix << stats.api_counts[static_cast<unsigned>(hiddenapi::ApiList::kLightGreylist)]
+      os << kPrefix << stats.api_counts[hiddenapi::ApiList::Greylist().GetIntValue()]
          << " in light greylist" << std::endl;
     }
   }