fix native shell ticking resident game
This commit is contained in:
parent
e19409a2ef
commit
a22215392d
@ -984,6 +984,15 @@ mod tests {
|
|||||||
assert_eq!(firmware.os.lifecycle().resident_game_task(), Some(game_task));
|
assert_eq!(firmware.os.lifecycle().resident_game_task(), Some(game_task));
|
||||||
assert_eq!(firmware.os.lifecycle().task_state(game_task), Some(TaskState::Suspended));
|
assert_eq!(firmware.os.lifecycle().task_state(game_task), Some(TaskState::Suspended));
|
||||||
|
|
||||||
|
let tick_index_before_native_shell_updates = firmware.os.vm().tick_index();
|
||||||
|
for _ in 0..61 {
|
||||||
|
firmware.tick(&signals, &mut platform);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(matches!(firmware.state, FirmwareState::ShellRunning(_)));
|
||||||
|
assert_eq!(firmware.os.vm().tick_index(), tick_index_before_native_shell_updates);
|
||||||
|
assert_eq!(firmware.os.lifecycle().task_state(game_task), Some(TaskState::Suspended));
|
||||||
|
|
||||||
let close_shell = InputSignals { start_signal: true, ..Default::default() };
|
let close_shell = InputSignals { start_signal: true, ..Default::default() };
|
||||||
firmware.tick(&close_shell, &mut platform);
|
firmware.tick(&close_shell, &mut platform);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep};
|
use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep};
|
||||||
use crate::firmware::prometeu_context::PrometeuContext;
|
use crate::firmware::prometeu_context::PrometeuContext;
|
||||||
use prometeu_hal::log::LogSource;
|
use prometeu_hal::log::LogSource;
|
||||||
|
use prometeu_system::process::ProcessKind;
|
||||||
use prometeu_system::task::{TaskId, TaskState};
|
use prometeu_system::task::{TaskId, TaskState};
|
||||||
use prometeu_system::{CrashReport, SystemProfileAction};
|
use prometeu_system::{CrashReport, SystemProfileAction};
|
||||||
|
|
||||||
@ -59,14 +60,53 @@ impl ShellRunningStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform);
|
let process_kind = match ctx.os.lifecycle().process_kind_for_task(self.task_id) {
|
||||||
|
Ok(process_kind) => process_kind,
|
||||||
|
Err(error) => {
|
||||||
|
let report = CrashReport::VmPanic {
|
||||||
|
message: format!(
|
||||||
|
"ShellRunningStep cannot resolve process for {:?}: {:?}",
|
||||||
|
self.task_id, error,
|
||||||
|
),
|
||||||
|
pc: None,
|
||||||
|
};
|
||||||
|
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(report) = outcome.crash {
|
let action = match process_kind {
|
||||||
let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report));
|
ProcessKind::VmShell => {
|
||||||
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
|
let outcome =
|
||||||
}
|
ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform);
|
||||||
|
|
||||||
if outcome.action == Some(SystemProfileAction::CloseShell) {
|
if let Some(report) = outcome.crash {
|
||||||
|
let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report));
|
||||||
|
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
|
||||||
|
}
|
||||||
|
|
||||||
|
outcome.action
|
||||||
|
}
|
||||||
|
ProcessKind::NativeShell => {
|
||||||
|
let mut action = ctx.hub.gui_update(ctx.os, ctx.platform);
|
||||||
|
if ctx.platform.input().pad().start().down {
|
||||||
|
action = Some(SystemProfileAction::CloseShell);
|
||||||
|
}
|
||||||
|
ctx.hub.render(ctx.os, ctx.platform);
|
||||||
|
action
|
||||||
|
}
|
||||||
|
ProcessKind::VmGame => {
|
||||||
|
let report = CrashReport::VmPanic {
|
||||||
|
message: format!(
|
||||||
|
"ShellRunningStep expected shell process for {:?}, got VmGame",
|
||||||
|
self.task_id,
|
||||||
|
),
|
||||||
|
pc: None,
|
||||||
|
};
|
||||||
|
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if action == Some(SystemProfileAction::CloseShell) {
|
||||||
self.close_current_shell(ctx);
|
self.close_current_shell(ctx);
|
||||||
return Some(FirmwareState::HubHome(HubHomeStep));
|
return Some(FirmwareState::HubHome(HubHomeStep));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::os::{
|
|||||||
DEFAULT_GAME_PAUSE_BUDGET_TICKS, GameLifecycleEvent, GameLifecycleEventKind, LifecycleError,
|
DEFAULT_GAME_PAUSE_BUDGET_TICKS, GameLifecycleEvent, GameLifecycleEventKind, LifecycleError,
|
||||||
LifecycleOperation,
|
LifecycleOperation,
|
||||||
};
|
};
|
||||||
use crate::process::{ProcessId, ProcessState};
|
use crate::process::{ProcessId, ProcessKind, ProcessState};
|
||||||
use crate::services::foreground::{
|
use crate::services::foreground::{
|
||||||
ForegroundOwner, ForegroundStackError, ResidentGame, ResidentGameState,
|
ForegroundOwner, ForegroundStackError, ResidentGame, ResidentGameState,
|
||||||
};
|
};
|
||||||
@ -28,6 +28,15 @@ impl<'a> LifecycleFacade<'a> {
|
|||||||
.ok_or(LifecycleError::ProcessNotFound(process_id))
|
.ok_or(LifecycleError::ProcessNotFound(process_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn process_kind_for_task(&self, task_id: TaskId) -> Result<ProcessKind, LifecycleError> {
|
||||||
|
let process_id = process_id_for_task(self.os, task_id)?;
|
||||||
|
self.os
|
||||||
|
.process_manager
|
||||||
|
.get(process_id)
|
||||||
|
.map(|process| process.kind)
|
||||||
|
.ok_or(LifecycleError::ProcessNotFound(process_id))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_foreground_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> {
|
pub fn set_foreground_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> {
|
||||||
match task_kind_for_task(self.os, task_id)? {
|
match task_kind_for_task(self.os, task_id)? {
|
||||||
TaskKind::Game => return self.set_game_foreground_task(task_id),
|
TaskKind::Game => return self.set_game_foreground_task(task_id),
|
||||||
|
|||||||
@ -141,7 +141,7 @@ impl SystemOS {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::os::{GameLifecycleEventKind, LifecycleError, LifecycleOperation};
|
use crate::os::{GameLifecycleEventKind, LifecycleError, LifecycleOperation};
|
||||||
use crate::process::ProcessState;
|
use crate::process::{ProcessKind, ProcessState};
|
||||||
use crate::services::foreground::{ForegroundOwner, ResidentGame, ResidentGameState};
|
use crate::services::foreground::{ForegroundOwner, ResidentGame, ResidentGameState};
|
||||||
use crate::task::{TaskId, TaskState};
|
use crate::task::{TaskId, TaskState};
|
||||||
|
|
||||||
@ -288,6 +288,21 @@ mod tests {
|
|||||||
assert_eq!(process_state_for_task(&os, game), ProcessState::Suspended);
|
assert_eq!(process_state_for_task(&os, game), ProcessState::Suspended);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lifecycle_exposes_process_kind_for_shell_tasks() {
|
||||||
|
let mut os = SystemOS::new(None);
|
||||||
|
let vm_shell = os.sessions().create_vm_shell_task(7, "Settings");
|
||||||
|
os.lifecycle().close_task(vm_shell).expect("vm shell should close");
|
||||||
|
|
||||||
|
let native_shell = os.sessions().create_native_shell_task(8, "Files");
|
||||||
|
|
||||||
|
assert_eq!(os.lifecycle().process_kind_for_task(vm_shell), Ok(ProcessKind::VmShell));
|
||||||
|
assert_eq!(
|
||||||
|
os.lifecycle().process_kind_for_task(native_shell),
|
||||||
|
Ok(ProcessKind::NativeShell)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn second_foreground_shell_is_rejected() {
|
fn second_foreground_shell_is_rejected() {
|
||||||
let mut os = SystemOS::new(None);
|
let mut os = SystemOS::new(None);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user