blob: 262021c1aefddcd4f27aae8ce64c2ed82651fddb [file] [log] [blame]
Alan Stokes8c840442021-11-26 15:54:30 +00001/*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Alan Stokes8c840442021-11-26 15:54:30 +000017use crate::instance_starter::CompOsInstance;
18use crate::odrefresh;
Alan Stokes8c840442021-11-26 15:54:30 +000019use android_system_composd::aidl::android::system::composd::{
20 ICompilationTask::ICompilationTask, ICompilationTaskCallback::ICompilationTaskCallback,
21};
22use android_system_composd::binder::{Interface, Result as BinderResult, Strong};
Alan Stokesac9aa1a2021-12-14 11:32:13 +000023use anyhow::Result;
Alan Stokes8c840442021-11-26 15:54:30 +000024use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
Alan Stokes46a1dff2021-12-14 10:56:05 +000025use compos_common::odrefresh::ExitCode;
Alan Stokes8c840442021-11-26 15:54:30 +000026use log::{error, warn};
Alan Stokes8c840442021-11-26 15:54:30 +000027use std::sync::{Arc, Mutex};
28use std::thread;
29
30#[derive(Clone)]
31pub struct OdrefreshTask {
32 running_task: Arc<Mutex<Option<RunningTask>>>,
33}
34
35impl Interface for OdrefreshTask {}
36
37impl ICompilationTask for OdrefreshTask {
38 fn cancel(&self) -> BinderResult<()> {
39 let task = self.take();
40 // Drop the VM, which should end compilation - and cause our thread to exit
41 drop(task);
42 Ok(())
43 }
44}
45
46impl OdrefreshTask {
47 /// Return the current running task, if any, removing it from this CompilationTask.
48 /// Once removed, meaning the task has ended or been canceled, further calls will always return
49 /// None.
50 fn take(&self) -> Option<RunningTask> {
51 self.running_task.lock().unwrap().take()
52 }
53
54 pub fn start(
55 comp_os: Arc<CompOsInstance>,
Alan Stokesac9aa1a2021-12-14 11:32:13 +000056 target_dir_name: String,
Alan Stokes8c840442021-11-26 15:54:30 +000057 callback: &Strong<dyn ICompilationTaskCallback>,
58 ) -> Result<OdrefreshTask> {
59 let service = comp_os.get_service();
60 let task = RunningTask { comp_os, callback: callback.clone() };
61 let task = OdrefreshTask { running_task: Arc::new(Mutex::new(Some(task))) };
62
Alan Stokesac9aa1a2021-12-14 11:32:13 +000063 task.clone().start_thread(service, target_dir_name);
Alan Stokes8c840442021-11-26 15:54:30 +000064
65 Ok(task)
66 }
67
Alan Stokesac9aa1a2021-12-14 11:32:13 +000068 fn start_thread(self, service: Strong<dyn ICompOsService>, target_dir_name: String) {
Alan Stokes8c840442021-11-26 15:54:30 +000069 thread::spawn(move || {
Alan Stokesac9aa1a2021-12-14 11:32:13 +000070 let exit_code = odrefresh::run_in_vm(service, &target_dir_name);
Alan Stokes8c840442021-11-26 15:54:30 +000071
72 let task = self.take();
73 // We don't do the callback if cancel has already happened.
74 if let Some(task) = task {
75 let result = match exit_code {
Alan Stokes46a1dff2021-12-14 10:56:05 +000076 Ok(ExitCode::CompilationSuccess) => task.callback.onSuccess(),
Alan Stokes8c840442021-11-26 15:54:30 +000077 Ok(exit_code) => {
78 error!("Unexpected odrefresh result: {:?}", exit_code);
79 task.callback.onFailure()
80 }
81 Err(e) => {
82 error!("Running odrefresh failed: {:?}", e);
83 task.callback.onFailure()
84 }
85 };
86 if let Err(e) = result {
87 warn!("Failed to deliver callback: {:?}", e);
88 }
89 }
90 });
91 }
92}
93
Alan Stokes8c840442021-11-26 15:54:30 +000094struct RunningTask {
95 callback: Strong<dyn ICompilationTaskCallback>,
96 #[allow(dead_code)] // Keeps the CompOS VM alive
97 comp_os: Arc<CompOsInstance>,
98}