AAPT2: Add convert command

This command allows a developer to convert their proto APK
(generated from the link phase using --proto-format) into
a binary APK suitable for use on device.

  aapt2 convert -o output.apk input.apk

Test: manual + make aapt2_tests
Change-Id: I10a7c33bb4b57006d01fe00a8bf92f78e04e7e50
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index d2dd5cf..ef97de3 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -29,20 +29,41 @@
 
 namespace aapt {
 
+constexpr static const char kApkResourceTablePath[] = "resources.arsc";
+constexpr static const char kProtoResourceTablePath[] = "resources.pb";
+constexpr static const char kAndroidManifestPath[] = "AndroidManifest.xml";
+
 // Info about an APK loaded in memory.
 class LoadedApk {
  public:
-  LoadedApk(
-      const Source& source,
-      std::unique_ptr<io::IFileCollection> apk,
-      std::unique_ptr<ResourceTable> table)
-      : source_(source), apk_(std::move(apk)), table_(std::move(table)) {}
-  virtual ~LoadedApk() = default;
+  // Loads both binary and proto APKs from disk.
+  static std::unique_ptr<LoadedApk> LoadApkFromPath(const ::android::StringPiece& path,
+                                                    IDiagnostics* diag);
+
+  // Loads a proto APK from the given file collection.
+  static std::unique_ptr<LoadedApk> LoadProtoApkFromFileCollection(
+      const Source& source, std::unique_ptr<io::IFileCollection> collection, IDiagnostics* diag);
+
+  // Loads a binary APK from the given file collection.
+  static std::unique_ptr<LoadedApk> LoadBinaryApkFromFileCollection(
+      const Source& source, std::unique_ptr<io::IFileCollection> collection, IDiagnostics* diag);
+
+  LoadedApk(const Source& source, std::unique_ptr<io::IFileCollection> apk,
+            std::unique_ptr<ResourceTable> table, std::unique_ptr<xml::XmlResource> manifest)
+      : source_(source),
+        apk_(std::move(apk)),
+        table_(std::move(table)),
+        manifest_(std::move(manifest)) {
+  }
 
   io::IFileCollection* GetFileCollection() {
     return apk_.get();
   }
 
+  const ResourceTable* GetResourceTable() const {
+    return table_.get();
+  }
+
   ResourceTable* GetResourceTable() {
     return table_.get();
   }
@@ -51,6 +72,10 @@
     return source_;
   }
 
+  const xml::XmlResource* GetManifest() const {
+    return manifest_.get();
+  }
+
   /**
    * Writes the APK on disk at the given path, while also removing the resource
    * files that are not referenced in the resource table.
@@ -71,11 +96,6 @@
                               const TableFlattenerOptions& options, FilterChain* filters,
                               IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
 
-  /** Inflates the AndroidManifest.xml file from the APK. */
-  std::unique_ptr<xml::XmlResource> InflateManifest(IAaptContext* context);
-
-  static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context,
-                                                    const android::StringPiece& path);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedApk);
@@ -83,6 +103,7 @@
   Source source_;
   std::unique_ptr<io::IFileCollection> apk_;
   std::unique_ptr<ResourceTable> table_;
+  std::unique_ptr<xml::XmlResource> manifest_;
 };
 
 }  // namespace aapt