use crate::CrashReport; use crate::os::SystemOS; use crate::os::{LifecycleError, LifecycleOperation}; use crate::process::{ProcessId, ProcessState}; use crate::task::{TaskId, TaskState}; pub struct LifecycleFacade<'a> { pub(in crate::os) os: &'a mut SystemOS, } impl<'a> LifecycleFacade<'a> { pub fn task_state(&self, task_id: TaskId) -> Option { self.os.task_manager.get(task_id).map(|task| task.state) } pub fn process_state_for_task(&self, task_id: TaskId) -> Result { let process_id = process_id_for_task(self.os, task_id)?; self.os .process_manager .get(process_id) .map(|process| process.state) .ok_or(LifecycleError::ProcessNotFound(process_id)) } pub fn set_foreground_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> { let process_id = process_id_for_task(self.os, task_id)?; self.os.task_manager.set_foreground(task_id); self.os.process_manager.mark_running(process_id); Ok(()) } pub fn suspend_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> { let process_id = process_id_for_task(self.os, task_id)?; self.os.task_manager.mark_suspended(task_id); self.os.process_manager.mark_suspended(process_id); Ok(()) } pub fn resume_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> { let task = self.os.task_manager.get(task_id).ok_or(LifecycleError::TaskNotFound(task_id))?; if task.state != TaskState::Suspended { return Err(LifecycleError::InvalidTransition { task_id, from: task.state, operation: LifecycleOperation::Resume, }); } let process_id = process_id_for_task(self.os, task_id)?; self.os.task_manager.set_foreground(task_id); self.os.process_manager.mark_running(process_id); Ok(()) } pub fn close_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> { let process_id = process_id_for_task(self.os, task_id)?; self.os.task_manager.close_task(task_id); self.os.process_manager.mark_stopped(process_id); Ok(()) } pub fn crash_task( &mut self, task_id: TaskId, _report: Option<&CrashReport>, ) -> Result<(), LifecycleError> { let process_id = process_id_for_task(self.os, task_id)?; self.os.task_manager.mark_crashed(task_id); self.os.process_manager.mark_crashed(process_id); Ok(()) } } fn process_id_for_task(os: &SystemOS, task_id: TaskId) -> Result { let task = os.task_manager.get(task_id).ok_or(LifecycleError::TaskNotFound(task_id))?; if !os.process_manager.contains(task.process_id) { return Err(LifecycleError::ProcessNotFound(task.process_id)); } Ok(task.process_id) }