Merge changes I8f7e63de,Ib38a0a1d

* changes:
  Support remote directories in authfs_service
  Also pass SYSTEMSERVERCLASSPATH to compsvc
diff --git a/authfs/aidl/com/android/virt/fs/AuthFsConfig.aidl b/authfs/aidl/com/android/virt/fs/AuthFsConfig.aidl
index dfccee5..2e3479c 100644
--- a/authfs/aidl/com/android/virt/fs/AuthFsConfig.aidl
+++ b/authfs/aidl/com/android/virt/fs/AuthFsConfig.aidl
@@ -16,11 +16,52 @@
 
 package com.android.virt.fs;
 
-import com.android.virt.fs.InputFdAnnotation;
-import com.android.virt.fs.OutputFdAnnotation;
-
 /** @hide */
 parcelable AuthFsConfig {
+    parcelable InputFdAnnotation {
+        /**
+         * File descriptor number to be passed to the program.  This is also the same file
+         * descriptor number used in the backend server.
+         */
+        int fd;
+    }
+
+    parcelable OutputFdAnnotation {
+        /**
+         * File descriptor number to be passed to the program.  This is also the same file
+         * descriptor number used in the backend server.
+         */
+        int fd;
+    }
+
+    parcelable InputDirFdAnnotation {
+        /**
+         * File descriptor number to be passed to the program.  This is also the same file
+         * descriptor number used in the backend server.
+         */
+        int fd;
+
+        /**
+         * A manifest file that includes serialized protobuf of
+         * android.security.fsverity.FSVerityDigests. The path must be accessible to the
+         * IAuthFsService.
+         */
+        String manifestPath;
+
+        /**
+         * Prefix path that should be stripped from the path in the manifest.
+         */
+        String prefix;
+    }
+
+    parcelable OutputDirFdAnnotation {
+        /**
+         * File descriptor number to be passed to the program.  This is also the same file
+         * descriptor number used in the backend server.
+         */
+        int fd;
+    }
+
     /** Port of the filesystem backend. */
     int port;
 
@@ -29,4 +70,10 @@
 
     /** Annotation for the remote output file descriptors. */
     OutputFdAnnotation[] outputFdAnnotations;
+
+    /** Annotation for the remote input directory descriptors. */
+    InputDirFdAnnotation[] inputDirFdAnnotations;
+
+    /** Annotation for the remote output directory descriptors. */
+    OutputDirFdAnnotation[] outputDirFdAnnotations;
 }
diff --git a/authfs/aidl/com/android/virt/fs/InputFdAnnotation.aidl b/authfs/aidl/com/android/virt/fs/InputFdAnnotation.aidl
deleted file mode 100644
index 3534a77..0000000
--- a/authfs/aidl/com/android/virt/fs/InputFdAnnotation.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.virt.fs;
-
-/** @hide */
-parcelable InputFdAnnotation {
-    /**
-     * File descriptor number to be passed to the program.  This is also the same file descriptor
-     * number used in the backend server.
-     */
-    int fd;
-}
diff --git a/authfs/aidl/com/android/virt/fs/OutputFdAnnotation.aidl b/authfs/aidl/com/android/virt/fs/OutputFdAnnotation.aidl
deleted file mode 100644
index 4e4e621..0000000
--- a/authfs/aidl/com/android/virt/fs/OutputFdAnnotation.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.virt.fs;
-
-/** @hide */
-parcelable OutputFdAnnotation {
-    /**
-     * File descriptor number to be passed to the program.  This is currently assumed to be same as
-     * the file descriptor number used in the backend server.
-     */
-    int fd;
-}
diff --git a/authfs/service/src/authfs.rs b/authfs/service/src/authfs.rs
index 1b05749..2d4f707 100644
--- a/authfs/service/src/authfs.rs
+++ b/authfs/service/src/authfs.rs
@@ -26,11 +26,11 @@
 use std::thread::sleep;
 use std::time::{Duration, Instant};
 
-use authfs_aidl_interface::aidl::com::android::virt::fs::IAuthFs::{BnAuthFs, IAuthFs};
-use authfs_aidl_interface::aidl::com::android::virt::fs::{
-    AuthFsConfig::AuthFsConfig, InputFdAnnotation::InputFdAnnotation,
-    OutputFdAnnotation::OutputFdAnnotation,
+use authfs_aidl_interface::aidl::com::android::virt::fs::AuthFsConfig::{
+    AuthFsConfig, InputDirFdAnnotation::InputDirFdAnnotation, InputFdAnnotation::InputFdAnnotation,
+    OutputDirFdAnnotation::OutputDirFdAnnotation, OutputFdAnnotation::OutputFdAnnotation,
 };
+use authfs_aidl_interface::aidl::com::android::virt::fs::IAuthFs::{BnAuthFs, IAuthFs};
 use authfs_aidl_interface::binder::{
     self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Strong,
 };
@@ -80,6 +80,8 @@
             &mountpoint,
             &config.inputFdAnnotations,
             &config.outputFdAnnotations,
+            &config.inputDirFdAnnotations,
+            &config.outputDirFdAnnotations,
             debuggable,
         )?;
         wait_until_authfs_ready(&child, &mountpoint).map_err(|e| {
@@ -121,29 +123,41 @@
 
 fn run_authfs(
     mountpoint: &OsStr,
-    in_fds: &[InputFdAnnotation],
-    out_fds: &[OutputFdAnnotation],
+    in_file_fds: &[InputFdAnnotation],
+    out_file_fds: &[OutputFdAnnotation],
+    in_dir_fds: &[InputDirFdAnnotation],
+    out_dir_fds: &[OutputDirFdAnnotation],
     debuggable: bool,
 ) -> Result<SharedChild> {
     let mut args = vec![mountpoint.to_owned(), OsString::from("--cid=2")];
     args.push(OsString::from("-o"));
     args.push(OsString::from("fscontext=u:object_r:authfs_fuse:s0"));
-    for conf in in_fds {
+    for conf in in_file_fds {
         // TODO(b/185178698): Many input files need to be signed and verified.
         // or can we use debug cert for now, which is better than nothing?
         args.push(OsString::from("--remote-ro-file-unverified"));
         args.push(OsString::from(conf.fd.to_string()));
     }
-    for conf in out_fds {
+    for conf in out_file_fds {
         args.push(OsString::from("--remote-new-rw-file"));
         args.push(OsString::from(conf.fd.to_string()));
     }
+    for conf in in_dir_fds {
+        args.push(OsString::from("--remote-ro-dir"));
+        // TODO(206869687): Replace /dev/null with the real path when possible.
+        args.push(OsString::from(format!("{}:{}:{}", conf.fd, conf.manifestPath, conf.prefix)));
+    }
+    for conf in out_dir_fds {
+        args.push(OsString::from("--remote-new-rw-dir"));
+        args.push(OsString::from(conf.fd.to_string()));
+    }
     if debuggable {
         args.push(OsString::from("--debug"));
     }
 
     let mut command = Command::new(AUTHFS_BIN);
     command.args(&args);
+    debug!("Spawn authfs: {:?}", command);
     SharedChild::spawn(&mut command).context("Spawn authfs")
 }
 
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 24b041c..f0c94c5 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -129,7 +129,7 @@
     /// A mapping file that describes the expecting file/directory structure and integrity metadata
     /// in the remote directory. The file contains serialized protobuf of
     /// android.security.fsverity.FSVerityDigests.
-    /// TODO(203251769): Really use the file when it's generated.
+    /// TODO(206869687): Really use the file when it's generated.
     #[allow(dead_code)]
     mapping_file_path: PathBuf,
 
@@ -252,7 +252,7 @@
             AuthFsEntry::ReadonlyDirectory { dir: InMemoryDir::new() },
         )?;
 
-        // TODO(203251769): Read actual path from config.mapping_file_path when it's generated.
+        // TODO(206869687): Read actual path from config.mapping_file_path when it's generated.
         let paths = vec![
             Path::new("/system/framework/framework.jar"),
             Path::new("/system/framework/services.jar"),
@@ -268,7 +268,7 @@
                     related_path,
                 )?;
                 let file_size = service.getFileSize(remote_file.get_remote_fd())?.try_into()?;
-                // TODO(203251769): Switch to VerifiedReadonly
+                // TODO(206869687): Switch to VerifiedReadonly
                 AuthFsEntry::UnverifiedReadonly { reader: remote_file, file_size }
             };
             authfs.add_entry_at_ro_dir_by_path(
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
index 70d48c2..c27c5cd 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
@@ -412,7 +412,7 @@
         // Setup
         String authfsInputDir = MOUNT_DIR + "/3";
         runFdServerOnAndroid("--open-dir 3:/system", "--ro-dirs 3");
-        // TODO(203251769): Replace /dev/null with real manifest file when it's generated. We
+        // TODO(206869687): Replace /dev/null with real manifest file when it's generated. We
         // currently hard-coded the files for the test manually, and ignore the integrity check.
         runAuthFsOnMicrodroid("--remote-ro-dir 3:/dev/null:/system --cid " + VMADDR_CID_HOST);
 
@@ -430,7 +430,7 @@
         // Setup
         String authfsInputDir = MOUNT_DIR + "/3";
         runFdServerOnAndroid("--open-dir 3:/system", "--ro-dirs 3");
-        // TODO(203251769): Replace /dev/null with real manifest file when it's generated. We
+        // TODO(206869687): Replace /dev/null with real manifest file when it's generated. We
         // currently hard-coded the files for the test manually, and ignore the integrity check.
         runAuthFsOnMicrodroid("--remote-ro-dir 3:/dev/null:/system --cid " + VMADDR_CID_HOST);
 
diff --git a/compos/aidl/com/android/compos/ICompOsService.aidl b/compos/aidl/com/android/compos/ICompOsService.aidl
index 34dee54..db746fd 100644
--- a/compos/aidl/com/android/compos/ICompOsService.aidl
+++ b/compos/aidl/com/android/compos/ICompOsService.aidl
@@ -38,7 +38,8 @@
      * TODO(198211396): Implement properly. We can't simply accepting the classpaths from Android
      * since they are not derived from staged APEX (besides security reasons).
      */
-    void initializeClasspaths(String bootClasspath, String dex2oatBootClasspath);
+    void initializeClasspaths(
+            String bootClasspath, String dex2oatBootClasspath, String systemServerClassPath);
 
     /**
      * Run dex2oat command with provided args, in a context that may be specified in FdAnnotation,
diff --git a/compos/composd/src/instance_starter.rs b/compos/composd/src/instance_starter.rs
index 4b3ac1b..3e18c3e 100644
--- a/compos/composd/src/instance_starter.rs
+++ b/compos/composd/src/instance_starter.rs
@@ -152,7 +152,11 @@
 
         // TODO(198211396): Implement correctly.
         service
-            .initializeClasspaths(&env::var("BOOTCLASSPATH")?, &env::var("DEX2OATBOOTCLASSPATH")?)
+            .initializeClasspaths(
+                &env::var("BOOTCLASSPATH")?,
+                &env::var("DEX2OATBOOTCLASSPATH")?,
+                &env::var("SYSTEMSERVERCLASSPATH")?,
+            )
             .context("Initializing *CLASSPATH")?;
         Ok(())
     }
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index 1499d4b..72dca14 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -23,8 +23,11 @@
 
 use crate::fsverity;
 use authfs_aidl_interface::aidl::com::android::virt::fs::{
-    AuthFsConfig::AuthFsConfig, IAuthFs::IAuthFs, IAuthFsService::IAuthFsService,
-    InputFdAnnotation::InputFdAnnotation, OutputFdAnnotation::OutputFdAnnotation,
+    AuthFsConfig::{
+        AuthFsConfig, InputFdAnnotation::InputFdAnnotation, OutputFdAnnotation::OutputFdAnnotation,
+    },
+    IAuthFs::IAuthFs,
+    IAuthFsService::IAuthFsService,
 };
 use authfs_aidl_interface::binder::{ParcelFileDescriptor, Strong};
 use compos_aidl_interface::aidl::com::android::compos::FdAnnotation::FdAnnotation;
@@ -148,6 +151,8 @@
             .iter()
             .map(|fd| OutputFdAnnotation { fd: *fd })
             .collect(),
+        inputDirFdAnnotations: vec![],
+        outputDirFdAnnotations: vec![],
     }
 }
 
diff --git a/compos/src/compsvc.rs b/compos/src/compsvc.rs
index 2a5534c..9d2f1dc 100644
--- a/compos/src/compsvc.rs
+++ b/compos/src/compsvc.rs
@@ -90,10 +90,12 @@
         &self,
         boot_classpath: &str,
         dex2oat_boot_classpath: &str,
+        system_server_classpath: &str,
     ) -> BinderResult<()> {
         // TODO(198211396): Implement correctly.
         env::set_var("BOOTCLASSPATH", boot_classpath);
         env::set_var("DEX2OATBOOTCLASSPATH", dex2oat_boot_classpath);
+        env::set_var("SYSTEMSERVERCLASSPATH", system_server_classpath);
         Ok(())
     }