virtualizationservice: clean up

This is a follow up of 21e9b928ef7683ecbfc6fff17a5b588c791d385a and
adfb76c3cf021ae645341e94f8e85ac46d6791ec.

* fix typo
* use more rusty style
* add more comments

Bug: n/a
Test: MicrodroidHostTestCases
Change-Id: I1e763defa062eb61e243438542893f0046165366
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index a0b5217..b841ad0 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -34,7 +34,7 @@
 use android_system_virtualizationservice::binder::{
     self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Status, Strong, ThreadState,
 };
-use anyhow::Result;
+use anyhow::{bail, Result};
 use disk::QcowFile;
 use log::{debug, error, warn};
 use microdroid_payload_config::{ApexConfig, VmPayloadConfig};
@@ -45,6 +45,7 @@
 use std::path::{Path, PathBuf};
 use std::sync::{Arc, Mutex, Weak};
 use vmconfig::VmConfig;
+use zip::ZipArchive;
 
 pub const BINDER_SERVICE_IDENTIFIER: &str = "android.system.virtualizationservice";
 
@@ -55,6 +56,11 @@
 /// Only processes running with one of these UIDs are allowed to call debug methods.
 const DEBUG_ALLOWED_UIDS: [u32; 2] = [0, 2000];
 
+/// The list of APEXes which microdroid requires.
+/// TODO(b/192200378) move this to microdroid.json?
+const MICRODROID_REQUIRED_APEXES: [&str; 4] =
+    ["com.android.adbd", "com.android.i18n", "com.android.os.statsd", "com.android.sdkext"];
+
 /// Implementation of `IVirtualizationService`, the entry point of the AIDL service.
 #[derive(Debug, Default)]
 pub struct VirtualizationService {
@@ -101,21 +107,19 @@
             )
         })?;
 
-        let mut opt_raw_config = None;
         let config = match config {
-            VirtualMachineConfig::AppConfig(config) => {
-                let raw_config = load_app_config(config, &temporary_directory).map_err(|e| {
+            VirtualMachineConfig::AppConfig(config) => BorrowedOrOwned::Owned(
+                load_app_config(config, &temporary_directory).map_err(|e| {
                     error!("Failed to load app config from {}: {}", &config.configPath, e);
                     new_binder_exception(
                         ExceptionCode::SERVICE_SPECIFIC,
                         format!("Failed to load app config from {}: {}", &config.configPath, e),
                     )
-                })?;
-                opt_raw_config.replace(raw_config);
-                opt_raw_config.as_ref().unwrap()
-            }
-            VirtualMachineConfig::RawConfig(config) => config,
+                })?,
+            ),
+            VirtualMachineConfig::RawConfig(config) => BorrowedOrOwned::Borrowed(config),
         };
+        let config = config.as_ref();
 
         // Assemble disk images if needed.
         let disks = config
@@ -289,23 +293,24 @@
     let idsig_file = config.idsig.as_ref().unwrap().as_ref();
     let config_path = &config.configPath;
 
-    let mut apk_zip = zip::ZipArchive::new(apk_file)?;
+    let mut apk_zip = ZipArchive::new(apk_file)?;
     let config_file = apk_zip.by_name(config_path)?;
     let vm_payload_config: VmPayloadConfig = serde_json::from_reader(config_file)?;
 
     let os_name = &vm_payload_config.os.name;
+    // For now, the only supported "os" value is "microdroid"
+    if os_name != "microdroid" {
+        bail!("unknown os: {}", os_name);
+    }
     let vm_config_path = PathBuf::from(format!("/apex/com.android.virt/etc/{}.json", os_name));
     let vm_config_file = File::open(vm_config_path)?;
     let mut vm_config = VmConfig::load(&vm_config_file)?;
 
     // 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() }),
+            MICRODROID_REQUIRED_APEXES.iter().map(|name| ApexConfig { name: name.to_string() }),
         );
         apexes.dedup_by(|a, b| a.name == b.name);
 
@@ -520,3 +525,19 @@
 fn new_binder_exception<T: AsRef<str>>(exception: ExceptionCode, message: T) -> Status {
     Status::new_exception(exception, CString::new(message.as_ref()).ok().as_deref())
 }
+
+/// Simple utility for referencing Borrowed or Owned. Similar to std::borrow::Cow, but
+/// it doesn't require that T implements Clone.
+enum BorrowedOrOwned<'a, T> {
+    Borrowed(&'a T),
+    Owned(T),
+}
+
+impl<'a, T> AsRef<T> for BorrowedOrOwned<'a, T> {
+    fn as_ref(&self) -> &T {
+        match self {
+            Self::Borrowed(b) => b,
+            Self::Owned(o) => &o,
+        }
+    }
+}