Print hiddenapi info in dexdump

Dexlayout gtest verifies that it prints the same info as dexdump.
This would not be true in the presence of hiddenapi data. Implement
printing the data in dexdump too.

Bug: 123150330
Test: m test-art-host-gtest-dexlayout_test
Change-Id: I9171a5daaf5174a5e22c87b02cf4c6ff6c2ee95f
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index c23524a..a412938 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -1203,6 +1203,15 @@
   });
 }
 
+static std::string GetHiddenapiFlagStr(uint32_t hiddenapi_flags) {
+  std::stringstream ss;
+  hiddenapi::ApiList api_list(hiddenapi_flags);
+  api_list.Dump(ss);
+  std::string str_api_list = ss.str();
+  std::transform(str_api_list.begin(), str_api_list.end(), str_api_list.begin(), ::toupper);
+  return str_api_list;
+}
+
 /*
  * Dumps a method.
  */
@@ -1220,12 +1229,19 @@
   char* typeDescriptor = strdup(signature.ToString().c_str());
   const char* backDescriptor = dex_file.StringByTypeIdx(pMethodId.class_idx_);
   char* accessStr = createAccessFlagStr(flags, kAccessForMethod);
+  const uint32_t hiddenapiFlags = method.GetHiddenapiFlags();
 
   if (gOptions.outputFormat == OUTPUT_PLAIN) {
     fprintf(gOutFile, "    #%d              : (in %s)\n", i, backDescriptor);
     fprintf(gOutFile, "      name          : '%s'\n", name);
     fprintf(gOutFile, "      type          : '%s'\n", typeDescriptor);
     fprintf(gOutFile, "      access        : 0x%04x (%s)\n", flags, accessStr);
+    if (hiddenapiFlags != 0u) {
+      fprintf(gOutFile,
+              "      hiddenapi     : 0x%04x (%s)\n",
+              hiddenapiFlags,
+              GetHiddenapiFlagStr(hiddenapiFlags).c_str());
+    }
     if (method.GetCodeItem() == nullptr) {
       fprintf(gOutFile, "      code          : (none)\n");
     } else {
@@ -1330,12 +1346,19 @@
   const char* typeDescriptor = dex_file.StringByTypeIdx(field_id.type_idx_);
   const char* backDescriptor = dex_file.StringByTypeIdx(field_id.class_idx_);
   char* accessStr = createAccessFlagStr(flags, kAccessForField);
+  const uint32_t hiddenapiFlags = field.GetHiddenapiFlags();
 
   if (gOptions.outputFormat == OUTPUT_PLAIN) {
     fprintf(gOutFile, "    #%d              : (in %s)\n", i, backDescriptor);
     fprintf(gOutFile, "      name          : '%s'\n", name);
     fprintf(gOutFile, "      type          : '%s'\n", typeDescriptor);
     fprintf(gOutFile, "      access        : 0x%04x (%s)\n", flags, accessStr);
+    if (hiddenapiFlags != 0u) {
+      fprintf(gOutFile,
+              "      hiddenapi     : 0x%04x (%s)\n",
+              hiddenapiFlags,
+              GetHiddenapiFlagStr(hiddenapiFlags).c_str());
+    }
     if (data != nullptr) {
       fputs("      value         : ", gOutFile);
       dumpEncodedValue(&dex_file, data);
@@ -1488,7 +1511,7 @@
   }
 
   // Fields and methods.
-  ClassAccessor accessor(*pDexFile, pClassDef);
+  ClassAccessor accessor(*pDexFile, pClassDef, /* parse_hiddenapi_class_data= */ true);
 
   // Prepare data for static fields.
   const u1* sData = pDexFile->GetEncodedStaticFieldValuesArray(pClassDef);