Merge "Don't write artifacts under staging"
diff --git a/compos/aidl/com/android/compos/ICompOsService.aidl b/compos/aidl/com/android/compos/ICompOsService.aidl
index 7af2ada..194180b 100644
--- a/compos/aidl/com/android/compos/ICompOsService.aidl
+++ b/compos/aidl/com/android/compos/ICompOsService.aidl
@@ -46,13 +46,18 @@
      *
      * The execution is based on the VM's APEX mounts, files on Android's /system (by accessing
      * through systemDirFd over AuthFS), and *CLASSPATH derived in the VM, to generate the same
-     * odrefresh output aritfacts to the output directory (through outputDirFd).
+     * odrefresh output artifacts to the output directory (through outputDirFd).
      *
-     * The caller/Android is allowed to specify the zygote arch (ro.zygote).
-     *
-     * @return a CompilationResult
+     * @param systemDirFd An fd referring to /system
+     * @param outputDirFd An fd referring to the output directory, ART_APEX_DATA
+     * @param stagingDirFd An fd referring to the staging directory, e.g. ART_APEX_DATA/staging
+     * @param targetDirName The sub-directory of the output directory to which artifacts are to be
+     *                      written (e.g. dalvik-cache)
+     * @param zygoteArch The zygote architecture (ro.zygote)
+     * @return odrefresh exit code
      */
-    CompilationResult odrefresh(int systemDirFd, int outputDirFd, String zygoteArch);
+    byte odrefresh(int systemDirFd, int outputDirFd, int stagingDirFd, String targetDirName,
+            String zygoteArch);
 
     /**
      * Run dex2oat command with provided args, in a context that may be specified in FdAnnotation,
diff --git a/compos/composd/src/odrefresh.rs b/compos/composd/src/odrefresh.rs
index 3f6bdf1..d6a3435 100644
--- a/compos/composd/src/odrefresh.rs
+++ b/compos/composd/src/odrefresh.rs
@@ -34,7 +34,9 @@
 
 // TODO: What if this changes?
 const EX_MAX: i8 = 78;
+
 const ODREFRESH_BIN: &str = "/apex/com.android.art/bin/odrefresh";
+const ART_APEX_DATA: &str = "/data/misc/apexdata/com.android.art";
 
 #[derive(Debug, PartialEq, Eq, FromPrimitive)]
 #[repr(i8)]
@@ -97,22 +99,27 @@
     }
 }
 
-pub fn run_in_vm(service: Strong<dyn ICompOsService>, _target_dir_name: &str) -> Result<ExitCode> {
-    // TODO: Use target_dir_name
+pub fn run_in_vm(service: Strong<dyn ICompOsService>, target_dir_name: &str) -> Result<ExitCode> {
     let staging_dir = open_dir(composd_native::palette_create_odrefresh_staging_directory()?)?;
     let system_dir = open_dir(Path::new("/system"))?;
+    let output_dir = open_dir(Path::new(ART_APEX_DATA))?;
 
     // Spawn a fd_server to serve the FDs.
     let fd_server_config = FdServerConfig {
         ro_dir_fds: vec![system_dir.as_raw_fd()],
-        rw_dir_fds: vec![staging_dir.as_raw_fd()],
+        rw_dir_fds: vec![staging_dir.as_raw_fd(), output_dir.as_raw_fd()],
         ..Default::default()
     };
     let fd_server_raii = fd_server_config.into_fd_server()?;
 
     let zygote_arch = system_properties::read("ro.zygote")?;
-    let exit_code =
-        service.odrefresh(system_dir.as_raw_fd(), staging_dir.as_raw_fd(), &zygote_arch)?.exitCode;
+    let exit_code = service.odrefresh(
+        system_dir.as_raw_fd(),
+        output_dir.as_raw_fd(),
+        staging_dir.as_raw_fd(),
+        target_dir_name,
+        &zygote_arch,
+    )?;
 
     drop(fd_server_raii);
     if let Some(exit_code) = FromPrimitive::from_i8(exit_code) {
diff --git a/compos/composd/src/service.rs b/compos/composd/src/service.rs
index 3f31adb..6ce462c 100644
--- a/compos/composd/src/service.rs
+++ b/compos/composd/src/service.rs
@@ -108,7 +108,7 @@
     ) -> Result<Strong<dyn ICompilationTask>> {
         let comp_os = self.instance_manager.start_test_instance().context("Starting CompOS")?;
 
-        let target_dir_name = "test-instance".to_owned();
+        let target_dir_name = "test-artifacts".to_owned();
         let task = OdrefreshTask::start(comp_os, target_dir_name, callback)?;
 
         Ok(BnCompilationTask::new_binder(task, BinderFeatures::default()))
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index 44b4049..f8a66c2 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -15,10 +15,10 @@
  */
 
 use anyhow::{anyhow, bail, Context, Result};
-use log::error;
+use log::{debug, error, info};
 use minijail::{self, Minijail};
 use std::env;
-use std::fs::{create_dir, File};
+use std::fs::File;
 use std::os::unix::io::{AsRawFd, RawFd};
 use std::path::{Path, PathBuf};
 
@@ -60,11 +60,13 @@
 
 pub fn odrefresh(
     odrefresh_path: &Path,
+    target_dir_name: &str,
     system_dir_fd: i32,
     output_dir_fd: i32,
+    staging_dir_fd: i32,
     zygote_arch: &str,
     authfs_service: Strong<dyn IAuthFsService>,
-) -> Result<CompilerOutput> {
+) -> Result<i8> {
     // Mount authfs (via authfs_service). The authfs instance unmounts once the `authfs` variable
     // is out of scope.
     let authfs_config = AuthFsConfig {
@@ -75,7 +77,10 @@
             manifestPath: "/dev/null".to_string(),
             prefix: "/system".to_string(),
         }],
-        outputDirFdAnnotations: vec![OutputDirFdAnnotation { fd: output_dir_fd }],
+        outputDirFdAnnotations: vec![
+            OutputDirFdAnnotation { fd: output_dir_fd },
+            OutputDirFdAnnotation { fd: staging_dir_fd },
+        ],
         ..Default::default()
     };
     let authfs = authfs_service.mount(&authfs_config)?;
@@ -91,26 +96,25 @@
     env::set_var("ART_APEX_DATA", &art_apex_data);
 
     let mut staging_dir = mountpoint;
-    staging_dir.push(output_dir_fd.to_string());
-    staging_dir.push("staging");
-    create_dir(&staging_dir)
-        .with_context(|| format!("Create staging directory {}", staging_dir.display()))?;
+    staging_dir.push(staging_dir_fd.to_string());
 
     let args = vec![
         "odrefresh".to_string(),
         format!("--zygote-arch={}", zygote_arch),
+        format!("--dalvik-cache={}", target_dir_name),
         "--no-refresh".to_string(),
         format!("--staging-dir={}", staging_dir.display()),
         "--force-compile".to_string(),
     ];
+    debug!("Running odrefresh with args: {:?}", &args);
     let jail = spawn_jailed_task(odrefresh_path, &args, Vec::new() /* fd_mapping */)
         .context("Spawn odrefresh")?;
     match jail.wait() {
         // TODO(161471326): On success, sign all files in the output directory.
-        Ok(()) => Ok(CompilerOutput::ExitCode(0)),
+        Ok(()) => Ok(0i8),
         Err(minijail::Error::ReturnCode(exit_code)) => {
-            error!("odrefresh failed with exit code {}", exit_code);
-            Ok(CompilerOutput::ExitCode(exit_code as i8))
+            info!("odrefresh exited with exit code {}", exit_code);
+            Ok(exit_code as i8)
         }
         Err(e) => {
             bail!("Unexpected minijail error: {}", e)
diff --git a/compos/src/compsvc.rs b/compos/src/compsvc.rs
index 19f2f47..4540cd8 100644
--- a/compos/src/compsvc.rs
+++ b/compos/src/compsvc.rs
@@ -106,9 +106,11 @@
         &self,
         system_dir_fd: i32,
         output_dir_fd: i32,
+        staging_dir_fd: i32,
+        target_dir_name: &str,
         zygote_arch: &str,
-    ) -> BinderResult<CompilationResult> {
-        if system_dir_fd < 0 || output_dir_fd < 0 {
+    ) -> BinderResult<i8> {
+        if system_dir_fd < 0 || output_dir_fd < 0 || staging_dir_fd < 0 {
             return Err(new_binder_exception(
                 ExceptionCode::ILLEGAL_ARGUMENT,
                 "The remote FDs are expected to be non-negative",
@@ -122,10 +124,12 @@
         }
 
         let authfs_service = get_authfs_service()?;
-        let output = odrefresh(
+        odrefresh(
             &self.odrefresh_path,
+            target_dir_name,
             system_dir_fd,
             output_dir_fd,
+            staging_dir_fd,
             zygote_arch,
             authfs_service,
         )
@@ -135,13 +139,7 @@
                 ExceptionCode::SERVICE_SPECIFIC,
                 format!("odrefresh failed: {}", e),
             )
-        })?;
-        match output {
-            CompilerOutput::ExitCode(exit_code) => {
-                Ok(CompilationResult { exitCode: exit_code, ..Default::default() })
-            }
-            _ => Err(new_binder_exception(ExceptionCode::SERVICE_SPECIFIC, "odrefresh failed")),
-        }
+        })
     }
 
     fn compile_cmd(