Merge changes I552122d0,I9171a5da

* changes:
  dexlayout: ProcessOffset in WriteHiddenapiClassData
  Print hiddenapi info in dexdump
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);
diff --git a/dexlayout/dex_writer.cc b/dexlayout/dex_writer.cc
index 143f5b0..268abe4 100644
--- a/dexlayout/dex_writer.cc
+++ b/dexlayout/dex_writer.cc
@@ -469,6 +469,7 @@
   DCHECK_EQ(header_->HiddenapiClassDatas().Size(), header_->ClassDefs().Size());
 
   stream->AlignTo(SectionAlignment(DexFile::kDexTypeHiddenapiClassData));
+  ProcessOffset(stream, &header_->HiddenapiClassDatas());
   const uint32_t start = stream->Tell();
 
   // Compute offsets for each class def and write the header.
@@ -989,6 +990,15 @@
   }
 }
 
+void DexWriter::ProcessOffset(Stream* stream, dex_ir::CollectionBase* item) {
+  if (compute_offsets_) {
+    item->SetOffset(stream->Tell());
+  } else {
+    // Not computing offsets, just use the one in the item.
+    stream->Seek(item->GetOffset());
+  }
+}
+
 std::unique_ptr<DexContainer> DexWriter::CreateDexContainer() const {
   return std::unique_ptr<DexContainer>(new DexWriter::Container);
 }
diff --git a/dexlayout/dex_writer.h b/dexlayout/dex_writer.h
index 98041d3..62247ec 100644
--- a/dexlayout/dex_writer.h
+++ b/dexlayout/dex_writer.h
@@ -271,6 +271,7 @@
   // Process an offset, if compute_offset is set, write into the dex ir item, otherwise read the
   // existing offset and use that for writing.
   void ProcessOffset(Stream* stream, dex_ir::Item* item);
+  void ProcessOffset(Stream* stream, dex_ir::CollectionBase* item);
 
   dex_ir::Header* const header_;
   DexLayout* const dex_layout_;