vmterminal: Run crosvm(virtiofs) from app domain

Bug: 378451265
Test: Launch terminal app - verify virtiofs mount points
Run basic I/O test on virtiofs mounts
Change-Id: Ic9e0d7f11b0795adacb8526414bb6d8e1fad0804
Signed-off-by: Akilesh Kailash <akailash@google.com>
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java b/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
index ab03049..bd1af49 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
@@ -16,6 +16,7 @@
 
 package com.android.virtualization.terminal;
 
+
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.Rect;
@@ -39,6 +40,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.Reader;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -209,13 +211,26 @@
                                 GUEST_GID,
                                 0007,
                                 "android",
-                                "android");
+                                "android",
+                                false, /* app domain is set to false so that crosvm is spin up as child of virtmgr */
+                                "");
                     }
                     return null;
                 }
+                Path socketPath = context.getFilesDir().toPath().resolve("internal.virtiofs");
+                Files.deleteIfExists(socketPath);
                 return new SharedPath(
-                        sharedPath, terminalUid, terminalUid, 0, 0, 0007, "internal", "internal");
-            } catch (NameNotFoundException e) {
+                        sharedPath,
+                        terminalUid,
+                        terminalUid,
+                        0,
+                        0,
+                        0007,
+                        "internal",
+                        "internal",
+                        true, /* app domain is set to true so that crosvm is spin up from app context */
+                        socketPath.toString());
+            } catch (NameNotFoundException | IOException e) {
                 return null;
             }
         }
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 55de0af..c2f7663 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -1018,7 +1018,12 @@
                 guest_gid: path.guestGid,
                 mask: path.mask,
                 tag: path.tag.clone(),
-                socket_path: temporary_directory.join(&path.socket).to_string_lossy().to_string(),
+                socket_path: temporary_directory
+                    .join(&path.socketPath)
+                    .to_string_lossy()
+                    .to_string(),
+                socket_fd: maybe_clone_file(&path.socketFd)?,
+                app_domain: path.appDomain,
             })
         })
         .collect()
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 1ccabec..a385b82 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -235,6 +235,8 @@
     pub mask: i32,
     pub tag: String,
     pub socket_path: String,
+    pub socket_fd: Option<File>,
+    pub app_domain: bool,
 }
 
 /// virtio-input device configuration from `external/crosvm/src/crosvm/config.rs`
@@ -912,6 +914,9 @@
 
 fn run_virtiofs(config: &CrosvmConfig) -> io::Result<()> {
     for shared_path in &config.shared_paths {
+        if shared_path.app_domain {
+            continue;
+        }
         let ugid_map_value = format!(
             "{} {} {} {} {} /",
             shared_path.guest_uid,
@@ -1267,12 +1272,23 @@
     }
 
     for shared_path in &config.shared_paths {
-        if let Err(e) = wait_for_file(&shared_path.socket_path, 5) {
-            bail!("Error waiting for file: {}", e);
+        if shared_path.app_domain {
+            if let Some(socket_fd) = &shared_path.socket_fd {
+                let socket_path =
+                    add_preserved_fd(&mut preserved_fds, socket_fd.try_clone().unwrap());
+                let raw_fd: i32 = socket_path.rsplit_once('/').unwrap().1.parse().unwrap();
+                command
+                    .arg("--vhost-user-fs")
+                    .arg(format!("tag={},socket-fd={}", &shared_path.tag, raw_fd));
+            }
+        } else {
+            if let Err(e) = wait_for_file(&shared_path.socket_path, 5) {
+                bail!("Error waiting for file: {}", e);
+            }
+            command
+                .arg("--vhost-user-fs")
+                .arg(format!("{},tag={}", &shared_path.socket_path, &shared_path.tag));
         }
-        command
-            .arg("--vhost-user-fs")
-            .arg(format!("{},tag={}", &shared_path.socket_path, &shared_path.tag));
     }
 
     debug!("Preserving FDs {:?}", preserved_fds);
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/SharedPath.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/SharedPath.aidl
index 7be7a5f..71ec02c 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/SharedPath.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/SharedPath.aidl
@@ -39,5 +39,11 @@
     String tag;
 
     /** socket name for vhost-user-fs */
-    String socket;
+    String socketPath;
+
+    /** socket fd for crosvm to connect */
+    @nullable ParcelFileDescriptor socketFd;
+
+    /** crosvm started from appDomain */
+    boolean appDomain;
 }