Support checking partitions for APEXes

Currently virtmgr only checks the root directory to find partitions of
files. But then vendor APEX files are regarded as non-vendor because
"apex" != "vendor". Preinstalled paths in apex info list must be used.

Bug: 383969737
Test: run vm tool with vendor APEX files
Change-Id: If93e22c733b085a049f2f78d7b71f9f919eae5be
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 15a80a6..2524ce7 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -20,7 +20,7 @@
 use crate::crosvm::{AudioConfig, CrosvmConfig, DiskFile, SharedPathConfig, DisplayConfig, GpuConfig, InputDeviceOption, PayloadState, UsbConfig, VmContext, VmInstance, VmState};
 use crate::debug_config::{DebugConfig, DebugPolicy};
 use crate::dt_overlay::{create_device_tree_overlay, VM_DT_OVERLAY_MAX_SIZE, VM_DT_OVERLAY_PATH};
-use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images, add_microdroid_vendor_image};
+use crate::payload::{ApexInfoList, add_microdroid_payload_images, add_microdroid_system_images, add_microdroid_vendor_image};
 use crate::selinux::{check_tee_service_permission, getfilecon, getprevcon, SeContext};
 use android_os_permissions_aidl::aidl::android::os::IPermissionController;
 use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::{
@@ -407,9 +407,33 @@
 }
 
 fn find_partition(path: &Path) -> binder::Result<String> {
-    match path.components().nth(1) {
+    let mut components = path.components();
+    match components.nth(1) {
         Some(std::path::Component::Normal(partition)) => {
-            Ok(partition.to_string_lossy().into_owned())
+            if partition != "apex" {
+                return Ok(partition.to_string_lossy().into_owned());
+            }
+
+            // If path is under /apex, find a partition of the preinstalled .apex path
+            let apex_name = match components.next() {
+                Some(std::path::Component::Normal(name)) => name.to_string_lossy(),
+                _ => {
+                    return Err(anyhow!("Can't find apex name for '{}'", path.display()))
+                        .or_service_specific_exception(-1)
+                }
+            };
+
+            let apex_info_list = ApexInfoList::load()
+                .context("Failed to get apex info list")
+                .or_service_specific_exception(-1)?;
+
+            for apex_info in apex_info_list.list.iter() {
+                if apex_info.name == apex_name {
+                    return Ok(apex_info.partition.to_lowercase());
+                }
+            }
+
+            Err(anyhow!("Can't find apex info for '{apex_name}'")).or_service_specific_exception(-1)
         }
         _ => Err(anyhow!("Can't find partition in '{}'", path.display()))
             .or_service_specific_exception(-1),
diff --git a/android/virtmgr/src/payload.rs b/android/virtmgr/src/payload.rs
index 5811314..bd6bf10 100644
--- a/android/virtmgr/src/payload.rs
+++ b/android/virtmgr/src/payload.rs
@@ -48,15 +48,19 @@
 
 /// Represents the list of APEXes
 #[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
-struct ApexInfoList {
+pub(crate) struct ApexInfoList {
+    /// The list of APEXes
     #[serde(rename = "apex-info")]
-    list: Vec<ApexInfo>,
+    pub(crate) list: Vec<ApexInfo>,
 }
 
+/// Represents info of an APEX
 #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
-struct ApexInfo {
+pub(crate) struct ApexInfo {
+    /// Name of APEX
     #[serde(rename = "moduleName")]
-    name: String,
+    pub(crate) name: String,
+
     #[serde(rename = "versionCode")]
     version: u64,
     #[serde(rename = "modulePath")]
@@ -80,11 +84,15 @@
 
     #[serde(rename = "preinstalledModulePath")]
     preinstalled_path: PathBuf,
+
+    /// Partition of APEX
+    #[serde(default)]
+    pub(crate) partition: String,
 }
 
 impl ApexInfoList {
     /// Loads ApexInfoList
-    fn load() -> Result<&'static ApexInfoList> {
+    pub(crate) fn load() -> Result<&'static ApexInfoList> {
         static INSTANCE: OnceCell<ApexInfoList> = OnceCell::new();
         INSTANCE.get_or_try_init(|| {
             let apex_info_list = File::open(APEX_INFO_LIST_PATH)