microdroid: add "apk" to payload am: 57d895e89f

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/1705202

Change-Id: I355471bfa90bc5fc5ec6489d4229e92b9ad73358
diff --git a/microdroid/signature/microdroid_signature.proto b/microdroid/signature/microdroid_signature.proto
index 8335ff5..8816aa8 100644
--- a/microdroid/signature/microdroid_signature.proto
+++ b/microdroid/signature/microdroid_signature.proto
@@ -25,6 +25,8 @@
   // Lists the signature information of the payload apexes.
   // The payload apexes are mapped to the partitions following the signature partition.
   repeated ApexSignature apexes = 2;
+
+  ApkSignature apk = 3;
 }
 
 message ApexSignature {
@@ -44,3 +46,12 @@
   // When specified, the root digest of the apex should match with it.
   string rootDigest = 4;
 }
+
+message ApkSignature {
+  // Required.
+  // The name of APK.
+  string name = 1;
+
+  string payload_partition_name = 2;
+  string idsig_partition_name = 3;
+}
\ No newline at end of file
diff --git a/microdroid/signature/mk_payload.cc b/microdroid/signature/mk_payload.cc
index 0ea4d2c..a3501d4 100644
--- a/microdroid/signature/mk_payload.cc
+++ b/microdroid/signature/mk_payload.cc
@@ -38,6 +38,7 @@
 using android::base::Result;
 using android::base::unique_fd;
 using android::microdroid::ApexSignature;
+using android::microdroid::ApkSignature;
 using android::microdroid::MicrodroidSignature;
 using android::microdroid::WriteMicrodroidSignature;
 
@@ -84,11 +85,18 @@
     std::optional<std::string> root_digest;
 };
 
+struct ApkConfig {
+    std::string name;
+    // TODO(jooyung): find path/idsig with name
+    std::string path;
+};
+
 struct Config {
     std::string dirname; // config file's direname to resolve relative paths in the config
 
     std::vector<std::string> system_apexes;
     std::vector<ApexConfig> apexes;
+    std::optional<ApkConfig> apk;
 };
 
 #define DO(expr) \
@@ -102,7 +110,8 @@
     return {};
 }
 
-Result<void> ParseJson(const Json::Value& value, std::optional<std::string>& s) {
+template <typename T>
+Result<void> ParseJson(const Json::Value& value, std::optional<T>& s) {
     if (value.isNull()) {
         s.reset();
         return {};
@@ -119,6 +128,12 @@
     return {};
 }
 
+Result<void> ParseJson(const Json::Value& value, ApkConfig& apk_config) {
+    DO(ParseJson(value["name"], apk_config.name));
+    DO(ParseJson(value["path"], apk_config.path));
+    return {};
+}
+
 template <typename T>
 Result<void> ParseJson(const Json::Value& values, std::vector<T>& parsed) {
     for (const Json::Value& value : values) {
@@ -132,6 +147,7 @@
 Result<void> ParseJson(const Json::Value& value, Config& config) {
     DO(ParseJson(value["system_apexes"], config.system_apexes));
     DO(ParseJson(value["apexes"], config.apexes));
+    DO(ParseJson(value["apk"], config.apk));
     return {};
 }
 
@@ -209,6 +225,13 @@
         }
     }
 
+    if (config.apk.has_value()) {
+        ApkSignature* apk_signature = signature.mutable_apk();
+        apk_signature->set_name(config.apk->name);
+        apk_signature->set_payload_partition_name("microdroid-apk");
+        // TODO(jooyung): set idsig partition as well
+    }
+
     std::ofstream out(filename);
     return WriteMicrodroidSignature(signature, out);
 }
@@ -249,20 +272,37 @@
             .read_only = true,
     });
 
+    int filler_count = 0;
+    auto add_partition = [&](auto partition_name, auto file_path) -> Result<void> {
+        std::string filler_path = output_file + "." + std::to_string(filler_count++);
+        if (auto ret = GenerateFiller(file_path, filler_path); !ret.ok()) {
+            return ret.error();
+        }
+        partitions.push_back(MultipleImagePartition{
+                .label = partition_name,
+                .image_file_paths = {file_path, filler_path},
+                .type = kLinuxFilesystem,
+                .read_only = true,
+        });
+        return {};
+    };
+
     // put apexes at the subsequent partitions with "size" filler
     for (size_t i = 0; i < config.apexes.size(); i++) {
         const auto& apex_config = config.apexes[i];
         std::string apex_path = ToAbsolute(apex_config.path, config.dirname);
-        std::string filler_path = output_file + "." + std::to_string(i);
-        if (auto ret = GenerateFiller(apex_path, filler_path); !ret.ok()) {
+        if (auto ret = add_partition("microdroid-apex-" + std::to_string(i), apex_path);
+            !ret.ok()) {
             return ret.error();
         }
-        partitions.push_back(MultipleImagePartition{
-                .label = "microdroid-apex-" + std::to_string(i),
-                .image_file_paths = {apex_path, filler_path},
-                .type = kLinuxFilesystem,
-                .read_only = true,
-        });
+    }
+    // put apk with "size" filler if necessary.
+    // TODO(jooyung): partition name("microdroid-apk") is TBD
+    if (config.apk.has_value()) {
+        std::string apk_path = ToAbsolute(config.apk->path, config.dirname);
+        if (auto ret = add_partition("microdroid-apk", apk_path); !ret.ok()) {
+            return ret.error();
+        }
     }
 
     const std::string gpt_header = AppendFileName(output_file, "-header");