virtmgr: Support early VM from /system/[system_ext/product]

the early_vms.xml discovery logic shall support devices
where system_ext is not its own partition but a symlink of
/system/system_ext or /system/product.

Bug: TBD
Test: atest virtualizationmanager_device_test
Test: boot security_vm on Trusty QEMU
Change-Id: Ibd057bb1c509fa4c0870c1807e2d5d5ebf2c698f
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 0c5480b..3deb67c 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -425,6 +425,11 @@
         Some(path) => path,
         None => return Ok("system".to_owned()),
     };
+    if path.starts_with("/system/system_ext/") {
+        return Ok("system_ext".to_owned());
+    } else if path.starts_with("/system/product/") {
+        return Ok("product".to_owned());
+    }
     let mut components = path.components();
     match components.nth(1) {
         Some(std::path::Component::Normal(partition)) => {
@@ -482,7 +487,10 @@
                     .or_service_specific_exception(-1)
             }
         };
-        if Path::new(&early_vm.path) != calling_exe_path {
+        let expected_exe_path = Path::new(&early_vm.path);
+        if expected_exe_path != calling_exe_path
+            && Path::new("/system").join(expected_exe_path) != calling_exe_path
+        {
             return Err(anyhow!(
                 "VM '{name}' in partition '{calling_partition}' must be created with '{}', not '{}'",
                 &early_vm.path,
@@ -2635,6 +2643,22 @@
     }
 
     #[test]
+    fn test_symlink_to_system_ext_supported() -> Result<()> {
+        let link_path = Path::new("/system/system_ext/file");
+        let partition = find_partition(Some(link_path)).unwrap();
+        assert_eq!("system_ext", partition);
+        Ok(())
+    }
+
+    #[test]
+    fn test_symlink_to_product_supported() -> Result<()> {
+        let link_path = Path::new("/system/product/file");
+        let partition = find_partition(Some(link_path)).unwrap();
+        assert_eq!("product", partition);
+        Ok(())
+    }
+
+    #[test]
     fn test_duplicated_early_vms() -> Result<()> {
         let tmp_dir = tempfile::TempDir::new()?;
         let tmp_dir_path = tmp_dir.path().to_owned();