microdroid: create payload disk image with system apexes

Virtualizationservice creates a pyload disk image only for "microdroid"
and it adds necessary system apexes automatically.

Removed those apexes from vm_config.json files in testapk and compos
apk.

Bug: 190503456
Bug: 192200378
Test: adb root && adb shell setenforce 0
Test: adb shell /apex/com.android.virt/bin/vm run-app \
  /apex/com.android.compos/app/CompOSPayloadApp/CompOSPayloadApp.apk \
  /apex/com.android.compos/etc/CompOSPayloadApp.apk.idsig \
  assets/vm_config.json
Change-Id: I7d472ea0876f2571ca6767e2ba0b5773a951368b
diff --git a/compos/Android.bp b/compos/Android.bp
index 0cb6894..1eb6716 100644
--- a/compos/Android.bp
+++ b/compos/Android.bp
@@ -83,10 +83,3 @@
     prefer_rlib: true,
     apex_available: ["com.android.compos"],
 }
-
-// TODO(b/190503456) Remove this when vm/virtualizationservice generates payload.img from vm_config
-prebuilt_etc {
-    name: "compos_payload_config",
-    src: "payload_config.json",
-    filename: "payload_config.json",
-}
diff --git a/compos/apex/Android.bp b/compos/apex/Android.bp
index 9942e09..1fffa2e 100644
--- a/compos/apex/Android.bp
+++ b/compos/apex/Android.bp
@@ -48,6 +48,6 @@
     ],
 
     prebuilts: [
-        "compos_payload_config",
+        "CompOSPayloadApp.apk.idsig",
     ],
 }
diff --git a/compos/apk/Android.bp b/compos/apk/Android.bp
index c6192b9..c5d0c31 100644
--- a/compos/apk/Android.bp
+++ b/compos/apk/Android.bp
@@ -3,7 +3,42 @@
 }
 
 android_app {
-    name: "CompOSPayloadApp",
+    name: "CompOSPayloadApp.unsigned",
     sdk_version: "current",
     apex_available: ["com.android.compos"],
 }
+
+// TODO(b/190409306) this is temporal until we have a solid way to pass merkle tree
+java_genrule {
+    name: "CompOSPayloadApp.signing",
+    out: [
+        "CompOSPayloadApp.apk",
+        "CompOSPayloadApp.apk.idsig",
+    ],
+    srcs: [":CompOSPayloadApp.unsigned"],
+    tools: ["apksigner"],
+    tool_files: ["test.keystore"],
+    cmd: "$(location apksigner) sign " +
+        "--ks $(location test.keystore) " +
+        "--ks-pass=pass:testkey --key-pass=pass:testkey " +
+        "--in $(in) " +
+        "--out $(genDir)/CompOSPayloadApp.apk",
+    // $(genDir)/MicrodroidTestApp.apk.idsig is generated implicitly
+}
+
+android_app_import {
+    name: "CompOSPayloadApp",
+    // Make sure the build system doesn't try to resign the APK
+    dex_preopt: {
+        enabled: false,
+    },
+    apk: ":CompOSPayloadApp.signing{CompOSPayloadApp.apk}",
+    presigned: true,
+    filename: "CompOSPayloadApp.apk",
+    apex_available: ["com.android.compos"],
+}
+
+prebuilt_etc {
+    name: "CompOSPayloadApp.apk.idsig",
+    src: ":CompOSPayloadApp.signing{CompOSPayloadApp.apk.idsig}",
+}
diff --git a/compos/apk/assets/vm_config.json b/compos/apk/assets/vm_config.json
index a8dca71..f9f1f90 100644
--- a/compos/apk/assets/vm_config.json
+++ b/compos/apk/assets/vm_config.json
@@ -13,22 +13,10 @@
   },
   "apexes": [
     {
-      "name": "com.android.adbd"
-    },
-    {
       "name": "com.android.art"
     },
     {
       "name": "com.android.compos"
-    },
-    {
-      "name": "com.android.i18n"
-    },
-    {
-      "name": "com.android.os.statsd"
-    },
-    {
-      "name": "com.android.sdkext"
     }
   ]
 }
\ No newline at end of file
diff --git a/compos/apk/test.keystore b/compos/apk/test.keystore
new file mode 100644
index 0000000..2f024d8
--- /dev/null
+++ b/compos/apk/test.keystore
Binary files differ
diff --git a/compos/payload_config.json b/compos/payload_config.json
deleted file mode 100644
index 588ccca..0000000
--- a/compos/payload_config.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "apk": {
-    "path": "/apex/com.android.compos/app/CompOSPayloadApp/CompOSPayloadApp.apk",
-    "name": "com.android.compos.payload"
-  },
-  "system_apexes": [
-    "com.android.adbd",
-    "com.android.art",
-    "com.android.compos",
-    "com.android.i18n",
-    "com.android.os.statsd",
-    "com.android.sdkext"
-  ],
-  "payload_config_path": "/mnt/apk/assets/vm_config.json"
-}
\ No newline at end of file
diff --git a/microdroid/README.md b/microdroid/README.md
index 2d5f854..f48a35c 100644
--- a/microdroid/README.md
+++ b/microdroid/README.md
@@ -74,20 +74,13 @@
     "type": "microdroid_launcher",
     "command": "MyMicrodroidApp.so"
   },
-  "apexes": [
-    {"name": "com.android.adbd"},
-    {"name": "com.android.i18n"},
-    {"name": "com.android.os.statsd"},
-    {"name": "com.android.sdkext"}
-  ]
+  "apexes" : [ ... ]
 }
 ```
 
 The value of `task.command` should match with the name of the shared library
 defined above. The `apexes` array is the APEXes that will be imported to
-microdroid. The above four APEXes are essential ones and therefore shouldn't be
-omitted. In the future, you wouldn't need to add the default ones manually. If
-more APEXes are required for you app, add their names too.
+microdroid.
 
 Embed the shared library and the VM configuration file in an APK:
 
diff --git a/tests/testapk/assets/vm_config.json b/tests/testapk/assets/vm_config.json
index 8312f4d..b814394 100644
--- a/tests/testapk/assets/vm_config.json
+++ b/tests/testapk/assets/vm_config.json
@@ -9,19 +9,5 @@
       "hello",
       "microdroid"
     ]
-  },
-  "apexes": [
-    {
-      "name": "com.android.adbd"
-    },
-    {
-      "name": "com.android.i18n"
-    },
-    {
-      "name": "com.android.os.statsd"
-    },
-    {
-      "name": "com.android.sdkext"
-    }
-  ]
+  }
 }
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 3f1660e..a0b5217 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -34,10 +34,10 @@
 use android_system_virtualizationservice::binder::{
     self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Status, Strong, ThreadState,
 };
-use anyhow::Error;
+use anyhow::Result;
 use disk::QcowFile;
 use log::{debug, error, warn};
-use microdroid_payload_config::VmPayloadConfig;
+use microdroid_payload_config::{ApexConfig, VmPayloadConfig};
 use std::convert::TryInto;
 use std::ffi::CString;
 use std::fs::{File, create_dir};
@@ -284,7 +284,7 @@
 fn load_app_config(
     config: &VirtualMachineAppConfig,
     temporary_directory: &Path,
-) -> Result<VirtualMachineRawConfig, Error> {
+) -> Result<VirtualMachineRawConfig> {
     let apk_file = config.apk.as_ref().unwrap().as_ref();
     let idsig_file = config.idsig.as_ref().unwrap().as_ref();
     let config_path = &config.configPath;
@@ -298,13 +298,25 @@
     let vm_config_file = File::open(vm_config_path)?;
     let mut vm_config = VmConfig::load(&vm_config_file)?;
 
-    vm_config.disks.push(payload::make_disk_image(
-        format!("/proc/self/fd/{}", apk_file.as_raw_fd()).into(),
-        format!("/proc/self/fd/{}", idsig_file.as_raw_fd()).into(),
-        config_path,
-        &vm_payload_config.apexes,
-        temporary_directory,
-    )?);
+    // Microdroid requires additional payload disk image
+    if os_name == "microdroid" {
+        // TODO (b/192200378) move this to microdroid.json?
+        let mut apexes = vm_payload_config.apexes.clone();
+        apexes.extend(
+            ["com.android.adbd", "com.android.i18n", "com.android.os.statsd", "com.android.sdkext"]
+                .iter()
+                .map(|name| ApexConfig { name: name.to_string() }),
+        );
+        apexes.dedup_by(|a, b| a.name == b.name);
+
+        vm_config.disks.push(payload::make_disk_image(
+            format!("/proc/self/fd/{}", apk_file.as_raw_fd()).into(),
+            format!("/proc/self/fd/{}", idsig_file.as_raw_fd()).into(),
+            config_path,
+            &apexes,
+            temporary_directory,
+        )?);
+    }
 
     vm_config.to_parcelable()
 }