Make composd API more async

Allow for notification on success/failure and for early cancellation.

Remove the old fully synchronous API.

Migrate the test to use the API (via modifying the composd_cmd tool).

Bug: 204044765
Test: atest ComposTestCase
Test: manual - make timeout very short, observe cancellation
Change-Id: I1d614ed60bc8baa9d4e58c1ca915e2093aec0808
diff --git a/compos/composd/src/service.rs b/compos/composd/src/service.rs
index d3b73a1..351eae9 100644
--- a/compos/composd/src/service.rs
+++ b/compos/composd/src/service.rs
@@ -17,18 +17,20 @@
 //! Implementation of IIsolatedCompilationService, called from system server when compilation is
 //! desired.
 
+use crate::compilation_task::CompilationTask;
 use crate::instance_manager::InstanceManager;
-use crate::odrefresh;
-use android_system_composd::aidl::android::system::composd::IIsolatedCompilationService::{
-    BnIsolatedCompilationService, IIsolatedCompilationService,
+use crate::util::to_binder_result;
+use android_system_composd::aidl::android::system::composd::{
+    ICompilationTask::{BnCompilationTask, ICompilationTask},
+    ICompilationTaskCallback::ICompilationTaskCallback,
+    IIsolatedCompilationService::{BnIsolatedCompilationService, IIsolatedCompilationService},
 };
 use android_system_composd::binder::{self, BinderFeatures, Interface, Strong};
-use anyhow::{bail, Context, Result};
+use anyhow::{Context, Result};
 use binder_common::new_binder_service_specific_error;
 use compos_aidl_interface::aidl::com::android::compos::{
     CompilationResult::CompilationResult, FdAnnotation::FdAnnotation,
 };
-use log::{error, info};
 
 pub struct IsolatedCompilationService {
     instance_manager: InstanceManager,
@@ -42,9 +44,12 @@
 impl Interface for IsolatedCompilationService {}
 
 impl IIsolatedCompilationService for IsolatedCompilationService {
-    fn runForcedCompileForTest(&self) -> binder::Result<()> {
+    fn startTestCompile(
+        &self,
+        callback: &Strong<dyn ICompilationTaskCallback>,
+    ) -> binder::Result<Strong<dyn ICompilationTask>> {
         // TODO - check caller is system or shell/root?
-        to_binder_result(self.do_run_forced_compile_for_test())
+        to_binder_result(self.do_start_test_compile(callback))
     }
 
     fn compile_cmd(
@@ -53,7 +58,7 @@
         fd_annotation: &FdAnnotation,
     ) -> binder::Result<CompilationResult> {
         // TODO - check caller is odrefresh
-        to_binder_result(self.do_compile(args, fd_annotation))
+        to_binder_result(self.do_compile_cmd(args, fd_annotation))
     }
 
     fn compile(&self, _marshaled: &[u8], _fd_annotation: &FdAnnotation) -> binder::Result<i8> {
@@ -61,33 +66,19 @@
     }
 }
 
-fn to_binder_result<T>(result: Result<T>) -> binder::Result<T> {
-    result.map_err(|e| {
-        let message = format!("{:?}", e);
-        error!("Returning binder error: {}", &message);
-        new_binder_service_specific_error(-1, message)
-    })
-}
-
 impl IsolatedCompilationService {
-    fn do_run_forced_compile_for_test(&self) -> Result<()> {
-        info!("runForcedCompileForTest");
-
+    fn do_start_test_compile(
+        &self,
+        callback: &Strong<dyn ICompilationTaskCallback>,
+    ) -> Result<Strong<dyn ICompilationTask>> {
         let comp_os = self.instance_manager.start_test_instance().context("Starting CompOS")?;
 
-        let exit_code = odrefresh::run_forced_compile("test-artifacts")?;
+        let task = CompilationTask::start_test_compile(comp_os, callback)?;
 
-        if exit_code != odrefresh::ExitCode::CompilationSuccess {
-            bail!("Unexpected odrefresh result: {:?}", exit_code);
-        }
-
-        // The instance is needed until odrefresh is finished
-        drop(comp_os);
-
-        Ok(())
+        Ok(BnCompilationTask::new_binder(task, BinderFeatures::default()))
     }
 
-    fn do_compile(
+    fn do_compile_cmd(
         &self,
         args: &[String],
         fd_annotation: &FdAnnotation,