Use input-vdex-fd, or input-vdex in dex2oat.

input-vdex-fd is used by installd
input-vdex is used by run-tests, and (will be used by) go/lem

This change copies the contents of the passed vdex to the new one,
unquicken the new vdex, and run the fast verification on the new
vdex.

bug:30937355
Test: device boots, apps get updated faster with vdex
Test: set TEST_VDEX to true in run-test-jar, run all tests
Test: 628-vdex

Change-Id: Idfbac4de411cebcf8ea7a6af7a417d7c7908dd72
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index b3dab58..843be92 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -20,6 +20,7 @@
 
 #include "base/logging.h"
 #include "base/unix_file/fd_file.h"
+#include "dex_file.h"
 
 namespace art {
 
@@ -73,10 +74,19 @@
     return nullptr;
   }
 
+  return Open(vdex_file->Fd(), vdex_length, vdex_filename, writable, low_4gb, error_msg);
+}
+
+VdexFile* VdexFile::Open(int file_fd,
+                         size_t vdex_length,
+                         const std::string& vdex_filename,
+                         bool writable,
+                         bool low_4gb,
+                         std::string* error_msg) {
   std::unique_ptr<MemMap> mmap(MemMap::MapFile(vdex_length,
                                                writable ? PROT_READ | PROT_WRITE : PROT_READ,
                                                MAP_SHARED,
-                                               vdex_file->Fd(),
+                                               file_fd,
                                                0 /* start offset */,
                                                low_4gb,
                                                vdex_filename.c_str(),
@@ -90,4 +100,16 @@
   return new VdexFile(mmap.release());
 }
 
+const uint8_t* VdexFile::GetNextDexFileData(const uint8_t* cursor) const {
+  DCHECK(cursor == nullptr || (cursor > Begin() && cursor <= End()));
+  if (cursor == nullptr) {
+    // Beginning of the iteration, return the first dex file if there is one.
+    return HasDexSection() ? DexBegin() : nullptr;
+  } else {
+    // Fetch the next dex file. Return null if there is none.
+    const uint8_t* data = cursor + reinterpret_cast<const DexFile::Header*>(cursor)->file_size_;
+    return (data == DexEnd()) ? nullptr : data;
+  }
+}
+
 }  // namespace art
diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h
index edd6ffe..75a0d5e 100644
--- a/runtime/vdex_file.h
+++ b/runtime/vdex_file.h
@@ -71,6 +71,13 @@
                         bool low_4gb,
                         std::string* error_msg);
 
+  static VdexFile* Open(int file_fd,
+                        size_t vdex_length,
+                        const std::string& vdex_filename,
+                        bool writable,
+                        bool low_4gb,
+                        std::string* error_msg);
+
   const uint8_t* Begin() const { return mmap_->Begin(); }
   const uint8_t* End() const { return mmap_->End(); }
   size_t Size() const { return mmap_->Size(); }
@@ -84,9 +91,37 @@
         Begin() + sizeof(Header) + GetHeader().GetDexSize(), GetHeader().GetVerifierDepsSize());
   }
 
+  ArrayRef<const uint8_t> GetQuickeningInfo() const {
+    return ArrayRef<const uint8_t>(
+        GetVerifierDepsData().data() + GetHeader().GetVerifierDepsSize(),
+        GetHeader().GetQuickeningInfoSize());
+  }
+
+  bool IsValid() const {
+    return mmap_->Size() >= sizeof(Header) && GetHeader().IsValid();
+  }
+
+  // This method is for iterating over the dex files in the vdex. If `cursor` is null,
+  // the first dex file is returned. If `cursor` is not null, it must point to a dex
+  // file and this method returns the next dex file if there is one, or null if there
+  // is none.
+  const uint8_t* GetNextDexFileData(const uint8_t* cursor) const;
+
  private:
   explicit VdexFile(MemMap* mmap) : mmap_(mmap) {}
 
+  bool HasDexSection() const {
+    return GetHeader().GetDexSize() != 0;
+  }
+
+  const uint8_t* DexBegin() const {
+    return Begin() + sizeof(Header);
+  }
+
+  const uint8_t* DexEnd() const {
+    return Begin() + sizeof(Header) + GetHeader().GetDexSize();
+  }
+
   std::unique_ptr<MemMap> mmap_;
 
   DISALLOW_COPY_AND_ASSIGN(VdexFile);