Add support for multiple GKI versions on VM

virt apex can now have multiple GKI versions for microdroid. Here are
behavior changes.

- OS name with "microdroid_gki-{ver}" is used to specify GKI.
- vm info shows available versions.
- gki option of vm tool gets a parameter, e.g. "--gki 6.1".

Some codes are refactored.

- Android.bp: defaults modules are added for deduplication.
- sign_virt_apex.py: gki_versions are added to remove hard-coded
  version (6.1).

Bug: 302465542
Test: vm info, vm run-microdroid --gki 6.1
Test: sign_virt_apex_test
Change-Id: I443a9e5a98d20d3c9337f2c13156590b4538c90b
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 87278bc..9a92f13 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -27,6 +27,7 @@
 use clap::{Args, Parser};
 use create_idsig::command_create_idsig;
 use create_partition::command_create_partition;
+use glob::glob;
 use run::{command_run, command_run_app, command_run_microdroid};
 use std::num::NonZeroU16;
 use std::path::{Path, PathBuf};
@@ -107,10 +108,10 @@
     #[arg(long)]
     devices: Vec<PathBuf>,
 
-    /// If set, use GKI instead of microdroid kernel
+    /// Version of GKI to use. If set, use instead of microdroid kernel
     #[cfg(vendor_modules)]
     #[arg(long)]
-    gki: bool,
+    gki: Option<String>,
 }
 
 impl MicrodroidConfig {
@@ -125,13 +126,13 @@
     }
 
     #[cfg(vendor_modules)]
-    fn gki(&self) -> bool {
-        self.gki
+    fn gki(&self) -> Option<&str> {
+        self.gki.as_deref()
     }
 
     #[cfg(not(vendor_modules))]
-    fn gki(&self) -> bool {
-        false
+    fn gki(&self) -> Option<&str> {
+        None
     }
 
     #[cfg(device_assignment)]
@@ -315,6 +316,12 @@
     Ok(())
 }
 
+fn extract_gki_version(gki_config: &Path) -> Option<&str> {
+    let name = gki_config.file_name()?;
+    let name_str = name.to_str()?;
+    name_str.strip_prefix("microdroid_gki-")?.strip_suffix(".json")
+}
+
 /// Print information about supported VM types.
 fn command_info() -> Result<(), Error> {
     let non_protected_vm_supported = hypervisor_props::is_vm_supported()?;
@@ -354,6 +361,12 @@
     let devices = devices.into_iter().map(|x| x.node).collect::<Vec<_>>();
     println!("Assignable devices: {}", serde_json::to_string(&devices)?);
 
+    let gki_configs =
+        glob("/apex/com.android.virt/etc/microdroid_gki-*.json")?.collect::<Result<Vec<_>, _>>()?;
+    let gki_versions =
+        gki_configs.iter().filter_map(|x| extract_gki_version(x)).collect::<Vec<_>>();
+    println!("Available gki versions: {}", serde_json::to_string(&gki_versions)?);
+
     Ok(())
 }