Migrate composd to odrefresh-in-vm

Replace startTestCompile with what was startAsyncOdrefresh, and
migrate startStagedApexCompile to work the same way. That means
both of our scheduled jobs will now be using the new mechanism.

Remove some of the now redundant code.

Remove tests that were explicitly running the deprecated form.

Bug: 205750213
Bug: 210998077
Test: atest ComposHostTestCases
Test: Manually trigger both scheduled jobs, observe success
Change-Id: Ie9df53045a852a37330156c76ac25c74db907b46
diff --git a/compos/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl b/compos/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
index ec5f2f5..8156265 100644
--- a/compos/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
+++ b/compos/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
@@ -31,19 +31,6 @@
     ICompilationTask startStagedApexCompile(ICompilationTaskCallback callback);
 
     /**
-     * Run "odrefresh --dalvik-cache=pending-test --force-compile" in a test instance of CompOS.
-     *
-     * This compiles BCP extensions and system server, even if the system artifacts are up to date,
-     * and writes the results to a test directory to avoid disrupting any real artifacts in
-     * existence.
-     *
-     * Compilation continues in the background, and success/failure is reported via the supplied
-     * callback, unless the returned ICompilationTask is cancelled. The caller should maintain
-     * a reference to the ICompilationTask until compilation completes or is cancelled.
-     */
-    ICompilationTask startTestCompile(ICompilationTaskCallback callback);
-
-    /**
      * Run odrefresh in a test instance of CompOS until completed or failed.
      *
      * This compiles BCP extensions and system server, even if the system artifacts are up to date,
@@ -54,5 +41,5 @@
      * callback, unless the returned ICompilationTask is cancelled. The caller should maintain
      * a reference to the ICompilationTask until compilation completes or is cancelled.
      */
-    ICompilationTask startAsyncOdrefresh(ICompilationTaskCallback callback);
+    ICompilationTask startTestCompile(ICompilationTaskCallback callback);
 }
diff --git a/compos/composd/src/compilation_task.rs b/compos/composd/src/compilation_task.rs
deleted file mode 100644
index 871c4fb..0000000
--- a/compos/composd/src/compilation_task.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 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.
- */
-
-use crate::instance_starter::CompOsInstance;
-use crate::odrefresh::Odrefresh;
-use android_system_composd::aidl::android::system::composd::{
-    ICompilationTask::ICompilationTask, ICompilationTaskCallback::ICompilationTaskCallback,
-};
-use android_system_composd::binder::{Interface, Result as BinderResult, Strong};
-use anyhow::Result;
-use compos_common::odrefresh::ExitCode;
-use log::{error, warn};
-use std::sync::{Arc, Mutex};
-use std::thread;
-
-// TODO: Delete
-
-#[derive(Clone)]
-pub struct CompilationTask {
-    running_task: Arc<Mutex<Option<RunningTask>>>,
-}
-
-impl Interface for CompilationTask {}
-
-impl ICompilationTask for CompilationTask {
-    fn cancel(&self) -> BinderResult<()> {
-        let task = self.take();
-        if let Some(task) = task {
-            if let Err(e) = task.odrefresh.kill() {
-                warn!("Failed to kill running task: {:?}", e)
-            }
-        }
-        Ok(())
-    }
-}
-
-impl CompilationTask {
-    /// Return the current running task, if any, removing it from this CompilationTask.
-    /// Once removed, meaning the task has ended or been canceled, further calls will always return
-    /// None.
-    fn take(&self) -> Option<RunningTask> {
-        self.running_task.lock().unwrap().take()
-    }
-
-    pub fn start_staged_apex_compile(
-        comp_os: Arc<CompOsInstance>,
-        callback: &Strong<dyn ICompilationTaskCallback>,
-    ) -> Result<CompilationTask> {
-        // TODO: Write to pending
-        // TODO: Delete any existing artifacts
-        let odrefresh = Odrefresh::spawn_compile("test-artifacts")?;
-        let odrefresh = Arc::new(odrefresh);
-        let task =
-            RunningTask { odrefresh: odrefresh.clone(), comp_os, callback: callback.clone() };
-        let task = CompilationTask { running_task: Arc::new(Mutex::new(Some(task))) };
-
-        task.clone().start_waiting_thread(odrefresh);
-
-        Ok(task)
-    }
-
-    pub fn start_test_compile(
-        comp_os: Arc<CompOsInstance>,
-        callback: &Strong<dyn ICompilationTaskCallback>,
-    ) -> Result<CompilationTask> {
-        let odrefresh = Odrefresh::spawn_forced_compile("test-artifacts")?;
-        let odrefresh = Arc::new(odrefresh);
-        let task =
-            RunningTask { odrefresh: odrefresh.clone(), comp_os, callback: callback.clone() };
-        let task = CompilationTask { running_task: Arc::new(Mutex::new(Some(task))) };
-
-        task.clone().start_waiting_thread(odrefresh);
-
-        Ok(task)
-    }
-
-    fn start_waiting_thread(self, odrefresh: Arc<Odrefresh>) {
-        thread::spawn(move || {
-            let exit_code = odrefresh.wait_for_exit();
-            let task = self.take();
-            // We don't do the callback if cancel has already happened.
-            if let Some(task) = task {
-                let result = match exit_code {
-                    Ok(ExitCode::CompilationSuccess) => task.callback.onSuccess(),
-                    Ok(exit_code) => {
-                        error!("Unexpected odrefresh result: {:?}", exit_code);
-                        task.callback.onFailure()
-                    }
-                    Err(e) => {
-                        error!("Running odrefresh failed: {:?}", e);
-                        task.callback.onFailure()
-                    }
-                };
-                if let Err(e) = result {
-                    warn!("Failed to deliver callback: {:?}", e);
-                }
-            }
-        });
-    }
-}
-
-struct RunningTask {
-    odrefresh: Arc<Odrefresh>,
-    callback: Strong<dyn ICompilationTaskCallback>,
-    #[allow(dead_code)] // Keeps the CompOS VM alive
-    comp_os: Arc<CompOsInstance>,
-}
diff --git a/compos/composd/src/composd_main.rs b/compos/composd/src/composd_main.rs
index 6f1e951..df088bc 100644
--- a/compos/composd/src/composd_main.rs
+++ b/compos/composd/src/composd_main.rs
@@ -18,12 +18,10 @@
 //! responsible for managing the lifecycle of the CompOS VM instances, providing key management for
 //! them, and orchestrating trusted compilation.
 
-mod compilation_task;
 mod fd_server_helper;
 mod instance_manager;
 mod instance_starter;
 mod internal_service;
-mod odrefresh;
 mod odrefresh_task;
 mod service;
 
diff --git a/compos/composd/src/odrefresh.rs b/compos/composd/src/odrefresh.rs
deleted file mode 100644
index a6ca995..0000000
--- a/compos/composd/src/odrefresh.rs
+++ /dev/null
@@ -1,76 +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.
- */
-
-//! Handle the details of executing odrefresh to generate compiled artifacts.
-
-// TODO: Delete
-
-use anyhow::{bail, Context, Result};
-use compos_common::odrefresh::{ExitCode, ODREFRESH_PATH};
-use compos_common::timeouts::{need_extra_time, EXTENDED_TIMEOUTS};
-use compos_common::VMADDR_CID_ANY;
-use shared_child::SharedChild;
-use std::process::Command;
-
-pub struct Odrefresh {
-    child: SharedChild,
-}
-
-impl Odrefresh {
-    pub fn spawn_compile(target_dir: &str) -> Result<Self> {
-        Self::spawn_odrefresh(target_dir, "--compile")
-    }
-
-    pub fn spawn_forced_compile(target_dir: &str) -> Result<Self> {
-        Self::spawn_odrefresh(target_dir, "--force-compile")
-    }
-
-    fn spawn_odrefresh(target_dir: &str, compile_arg: &str) -> Result<Self> {
-        // We don`t need to capture stdout/stderr - odrefresh writes to the log
-        let mut cmdline = Command::new(ODREFRESH_PATH);
-        if need_extra_time()? {
-            cmdline
-                .arg(format!(
-                    "--max-execution-seconds={}",
-                    EXTENDED_TIMEOUTS.odrefresh_max_execution_time.as_secs()
-                ))
-                .arg(format!(
-                    "--max-child-process-seconds={}",
-                    EXTENDED_TIMEOUTS.odrefresh_max_child_process_time.as_secs()
-                ));
-        }
-        cmdline
-            .arg(format!("--use-compilation-os={}", VMADDR_CID_ANY as i32))
-            .arg(format!("--dalvik-cache={}", target_dir))
-            .arg(compile_arg);
-        let child = SharedChild::spawn(&mut cmdline).context("Running odrefresh")?;
-        Ok(Odrefresh { child })
-    }
-
-    pub fn wait_for_exit(&self) -> Result<ExitCode> {
-        // No timeout here - but clients can kill the process, which will end the wait.
-        let status = self.child.wait()?;
-        if let Some(exit_code) = status.code() {
-            ExitCode::from_i32(exit_code)
-        } else {
-            bail!("odrefresh exited with {}", status)
-        }
-    }
-
-    pub fn kill(&self) -> Result<()> {
-        self.child.kill().context("Killing odrefresh process failed")
-    }
-}
diff --git a/compos/composd/src/service.rs b/compos/composd/src/service.rs
index 69cf008..093e428 100644
--- a/compos/composd/src/service.rs
+++ b/compos/composd/src/service.rs
@@ -17,7 +17,6 @@
 //! Implementation of IIsolatedCompilationService, called from system server when compilation is
 //! desired.
 
-use crate::compilation_task::CompilationTask;
 use crate::instance_manager::InstanceManager;
 use crate::odrefresh_task::OdrefreshTask;
 use android_system_composd::aidl::android::system::composd::{
@@ -62,14 +61,6 @@
         check_permissions()?;
         to_binder_result(self.do_start_test_compile(callback))
     }
-
-    fn startAsyncOdrefresh(
-        &self,
-        callback: &Strong<dyn ICompilationTaskCallback>,
-    ) -> binder::Result<Strong<dyn ICompilationTask>> {
-        check_permissions()?;
-        to_binder_result(self.do_start_async_odrefresh(callback))
-    }
 }
 
 impl IsolatedCompilationService {
@@ -80,7 +71,9 @@
         // TODO: Try to start the current instance with staged APEXes to see if it works?
         let comp_os = self.instance_manager.start_pending_instance().context("Starting CompOS")?;
 
-        let task = CompilationTask::start_staged_apex_compile(comp_os, callback)?;
+        // TODO: Write to compos-pending instead
+        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()))
     }
@@ -91,17 +84,6 @@
     ) -> Result<Strong<dyn ICompilationTask>> {
         let comp_os = self.instance_manager.start_test_instance().context("Starting CompOS")?;
 
-        let task = CompilationTask::start_test_compile(comp_os, callback)?;
-
-        Ok(BnCompilationTask::new_binder(task, BinderFeatures::default()))
-    }
-
-    fn do_start_async_odrefresh(
-        &self,
-        callback: &Strong<dyn ICompilationTaskCallback>,
-    ) -> Result<Strong<dyn ICompilationTask>> {
-        let comp_os = self.instance_manager.start_test_instance().context("Starting CompOS")?;
-
         let target_dir_name = "test-artifacts".to_owned();
         let task = OdrefreshTask::start(comp_os, target_dir_name, callback)?;
 
diff --git a/compos/composd_cmd/composd_cmd.rs b/compos/composd_cmd/composd_cmd.rs
index 41e2b1a..546c4af 100644
--- a/compos/composd_cmd/composd_cmd.rs
+++ b/compos/composd_cmd/composd_cmd.rs
@@ -38,7 +38,7 @@
             .index(1)
             .takes_value(true)
             .required(true)
-            .possible_values(&["staged-apex-compile", "forced-compile-test", "async-odrefresh"]),
+            .possible_values(&["staged-apex-compile", "test-compile"]),
     );
     let args = app.get_matches();
     let command = args.value_of("command").unwrap();
@@ -47,8 +47,7 @@
 
     match command {
         "staged-apex-compile" => run_staged_apex_compile()?,
-        "forced-compile-test" => run_forced_compile_for_test()?,
-        "async-odrefresh" => run_async_odrefresh_for_test()?,
+        "test-compile" => run_test_compile()?,
         _ => panic!("Unexpected command {}", command),
     }
 
@@ -109,14 +108,10 @@
     run_async_compilation(|service, callback| service.startStagedApexCompile(callback))
 }
 
-fn run_forced_compile_for_test() -> Result<()> {
+fn run_test_compile() -> Result<()> {
     run_async_compilation(|service, callback| service.startTestCompile(callback))
 }
 
-fn run_async_odrefresh_for_test() -> Result<()> {
-    run_async_compilation(|service, callback| service.startAsyncOdrefresh(callback))
-}
-
 fn run_async_compilation<F>(start_compile_fn: F) -> Result<()>
 where
     F: FnOnce(
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/compos/tests/java/android/compos/test/ComposTestCase.java
index e64a07e..7b027de 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/compos/tests/java/android/compos/test/ComposTestCase.java
@@ -104,7 +104,7 @@
             long start = System.currentTimeMillis();
             result =
                     android.runForResultWithTimeout(
-                            ODREFRESH_TIMEOUT_MS, COMPOSD_CMD_BIN, "async-odrefresh");
+                            ODREFRESH_TIMEOUT_MS, COMPOSD_CMD_BIN, "test-compile");
             long elapsed = System.currentTimeMillis() - start;
             assertThat(result.getExitCode()).isEqualTo(0);
             CLog.i("Comp OS compilation took " + elapsed + "ms");
@@ -123,52 +123,6 @@
         android.assumeSuccess("test -f " + ODREFRESH_OUTPUT_DIR + "/compos.info.signature");
     }
 
-    @Test
-    public void testOdrefreshDeprecated() throws Exception {
-        CommandRunner android = new CommandRunner(getDevice());
-
-        // Prepare the groundtruth. The compilation on Android should finish successfully.
-        {
-            long start = System.currentTimeMillis();
-            CommandResult result = runOdrefresh(android, "--force-compile");
-            long elapsed = System.currentTimeMillis() - start;
-            assertThat(result.getExitCode()).isEqualTo(COMPILATION_SUCCESS);
-            CLog.i("Local compilation took " + elapsed + "ms");
-        }
-
-        // Save the expected checksum for the output directory.
-        String expectedChecksumSnapshot = checksumDirectoryContent(android, ODREFRESH_OUTPUT_DIR);
-
-        // Let --check clean up the output.
-        CommandResult result = runOdrefresh(android, "--check");
-        assertThat(result.getExitCode()).isEqualTo(OKAY);
-
-        // Make sure we generate a fresh instance
-        android.tryRun("rm", "-rf", COMPOS_TEST_ROOT);
-
-        // Expect the compilation in Compilation OS to finish successfully.
-        {
-            long start = System.currentTimeMillis();
-            result =
-                    android.runForResultWithTimeout(
-                            ODREFRESH_TIMEOUT_MS, COMPOSD_CMD_BIN, "forced-compile-test");
-            long elapsed = System.currentTimeMillis() - start;
-            assertThat(result.getExitCode()).isEqualTo(0);
-            CLog.i("Comp OS compilation took " + elapsed + "ms");
-        }
-        killVmAndReconnectAdb();
-
-        // Save the actual checksum for the output directory.
-        String actualChecksumSnapshot = checksumDirectoryContent(android, ODREFRESH_OUTPUT_DIR);
-
-        // Expect the output to be valid.
-        result = runOdrefresh(android, "--check");
-        assertThat(result.getExitCode()).isEqualTo(OKAY);
-
-        // Expect the output of Comp OS to be the same as compiled on Android.
-        assertThat(actualChecksumSnapshot).isEqualTo(expectedChecksumSnapshot);
-    }
-
     private CommandResult runOdrefresh(CommandRunner android, String command) throws Exception {
         return android.runForResultWithTimeout(
                 ODREFRESH_TIMEOUT_MS,
@@ -194,11 +148,6 @@
         android.tryRun("rm", "-rf", "/data/misc/virtualizationservice/*");
     }
 
-    private String checksumDirectoryContent(CommandRunner runner, String path) throws Exception {
-        // Sort by filename (second column) to make comparison easier.
-        return runner.run("find " + path + " -type f -exec sha256sum {} \\; | sort -k2");
-    }
-
     private String checksumDirectoryContentPartial(CommandRunner runner, String path)
             throws Exception {
         // Sort by filename (second column) to make comparison easier. Filter out compos.info and