use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::time::Instant;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AppState {
Launching,
Active,
Background,
Inactive,
Suspended,
Terminating,
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum StateTransition {
LaunchToActive,
ActiveToBackground,
BackgroundToActive,
ActiveToInactive,
InactiveToActive,
BackgroundToSuspended,
SuspendedToBackground,
AnyToTerminating,
}
#[derive(Debug, Clone)]
pub struct StateTransitionEvent {
pub from_state: AppState,
pub to_state: AppState,
pub transition: StateTransition,
pub timestamp: Instant,
pub reason: TransitionReason,
pub context: TransitionContext,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum TransitionReason {
UserAction,
SystemRequest,
LowMemory,
LowBattery,
ThermalPressure,
NetworkInterruption,
Timeout,
Error,
SystemSuspend,
SystemResume,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransitionContext {
pub available_memory_mb: usize,
pub battery_level_percent: u8,
pub cpu_temperature_celsius: f32,
pub network_connected: bool,
pub active_background_tasks: usize,
pub time_since_user_interaction_seconds: u64,
pub foreground_duration_seconds: u64,
pub background_duration_seconds: u64,
pub system_pressure: SystemPressureIndicators,
pub resource_usage: ResourceUsageSnapshot,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemPressureIndicators {
pub memory_pressure: crate::lifecycle::config::MemoryPressureLevel,
pub thermal_state: crate::lifecycle::config::ThermalLevel,
pub battery_state: crate::battery::BatteryLevel,
pub network_quality: NetworkQuality,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum NetworkQuality {
Excellent,
Good,
Fair,
Poor,
Disconnected,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceUsageSnapshot {
pub cpu_usage_percent: f32,
pub memory_usage_mb: usize,
pub gpu_usage_percent: Option<f32>,
pub network_usage_mbps: f32,
pub storage_io_mbps: f32,
pub active_models: usize,
pub inference_queue_size: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppCheckpoint {
pub app_state: AppState,
pub timestamp: u64, pub model_states: Vec<ModelState>,
pub cache_states: HashMap<String, CacheState>,
pub user_session: UserSessionState,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelState {
pub model_id: String,
pub load_state: ModelLoadState,
pub configuration: ModelConfiguration,
pub performance_metrics: ModelPerformanceMetrics,
pub last_access_timestamp: u64,
pub usage_count: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ModelLoadState {
Unloaded,
Loading,
Loaded,
Error,
Cached,
Compressed,
Offloaded,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheState {
pub size_bytes: usize,
pub item_count: usize,
pub last_access_timestamp: u64,
pub hit_rate_percent: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelConfiguration {
pub precision: ModelPrecision,
pub optimization_level: OptimizationLevel,
pub backend: ModelBackend,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ModelPrecision {
FP32,
FP16,
INT8,
INT4,
Dynamic,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum OptimizationLevel {
None,
Basic,
Aggressive,
UltraLowMemory,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ModelBackend {
CPU,
CoreML,
NNAPI,
Metal,
Vulkan,
Custom,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelPerformanceMetrics {
pub avg_inference_time_ms: f32,
pub memory_usage_mb: usize,
pub throughput_per_second: f32,
pub error_rate_percent: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskState {
pub task_id: String,
pub task_type: crate::lifecycle::config::TaskType,
pub status: LifecycleTaskStatus,
pub priority: crate::lifecycle::config::TaskPriority,
pub progress_percent: u8,
pub estimated_completion_seconds: Option<u64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum LifecycleTaskStatus {
Pending,
Running,
Paused,
Completed,
Failed,
Cancelled,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserSessionState {
pub session_start_timestamp: u64,
pub total_interaction_time_seconds: u64,
pub recent_interactions: Vec<UserInteraction>,
pub session_stats: SessionStatistics,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInteraction {
pub timestamp: u64,
pub interaction_type: InteractionType,
pub outcome: InteractionOutcome,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum InteractionType {
Touch,
Voice,
Gesture,
TextInput,
ModelInference,
Navigation,
Settings,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum InteractionOutcome {
Success,
Failure,
Cancelled,
Timeout,
Error,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionStatistics {
pub total_inferences: usize,
pub total_models_loaded: usize,
pub total_background_tasks: usize,
pub avg_response_time_ms: f32,
pub error_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemContext {
pub timestamp: u64,
pub device_info: SystemDeviceInfo,
pub resource_availability: ResourceAvailability,
pub network_status: NetworkStatus,
pub power_status: PowerStatus,
pub thermal_status: ThermalStatus,
pub active_processes: ProcessInfo,
pub system_load: SystemLoad,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemDeviceInfo {
pub device_model: String,
pub os_version: String,
pub cpu_cores: usize,
pub total_ram_mb: usize,
pub available_storage_mb: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceAvailability {
pub available_cpu_percent: f32,
pub available_memory_mb: usize,
pub available_gpu_percent: Option<f32>,
pub available_network_mbps: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkStatus {
pub connected: bool,
pub connection_type: NetworkConnectionType,
pub signal_strength_percent: u8,
pub quality: NetworkQuality,
pub data_usage_mb: f32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum NetworkConnectionType {
WiFi,
Cellular,
Ethernet,
Bluetooth,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PowerStatus {
pub battery_level_percent: u8,
pub charging_status: ChargingStatus,
pub power_save_mode: bool,
pub estimated_battery_life_minutes: Option<u32>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ChargingStatus {
Charging,
Discharging,
Full,
NotCharging,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThermalStatus {
pub cpu_temperature_celsius: f32,
pub gpu_temperature_celsius: Option<f32>,
pub thermal_state: crate::lifecycle::config::ThermalLevel,
pub throttling_active: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessInfo {
pub total_processes: usize,
pub active_processes: usize,
pub background_processes: usize,
pub process_memory_usage_mb: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemLoad {
pub load_1min: f32,
pub load_5min: f32,
pub load_15min: f32,
pub cpu_utilization_percent: f32,
pub memory_utilization_percent: f32,
}
pub struct AppStateManager {
current_state: AppState,
previous_state: AppState,
state_history: VecDeque<StateTransition>,
state_listeners: Vec<Box<dyn StateListener>>,
transition_handlers: HashMap<StateTransition, Box<dyn TransitionHandler>>,
}
pub trait StateListener: Send + Sync {
fn on_state_change(&self, event: &StateTransitionEvent);
}
pub trait TransitionHandler: Send + Sync {
fn handle_transition(
&self,
event: &StateTransitionEvent,
) -> Result<(), Box<dyn std::error::Error>>;
}
impl AppStateManager {
pub fn new() -> Self {
Self {
current_state: AppState::Unknown,
previous_state: AppState::Unknown,
state_history: VecDeque::new(),
state_listeners: Vec::new(),
transition_handlers: HashMap::new(),
}
}
pub fn current_state(&self) -> AppState {
self.current_state
}
pub fn previous_state(&self) -> AppState {
self.previous_state
}
pub fn transition_to_state(
&mut self,
new_state: AppState,
reason: TransitionReason,
context: TransitionContext,
) -> Result<(), Box<dyn std::error::Error>> {
let transition = self.determine_transition(self.current_state, new_state)?;
let event = StateTransitionEvent {
from_state: self.current_state,
to_state: new_state,
transition,
timestamp: Instant::now(),
reason,
context,
};
if let Some(handler) = self.transition_handlers.get(&transition) {
handler.handle_transition(&event)?;
}
self.previous_state = self.current_state;
self.current_state = new_state;
self.state_history.push_back(transition);
if self.state_history.len() > 100 {
self.state_history.pop_front();
}
for listener in &self.state_listeners {
listener.on_state_change(&event);
}
Ok(())
}
pub fn add_state_listener(&mut self, listener: Box<dyn StateListener>) {
self.state_listeners.push(listener);
}
pub fn add_transition_handler(
&mut self,
transition: StateTransition,
handler: Box<dyn TransitionHandler>,
) {
self.transition_handlers.insert(transition, handler);
}
pub fn get_state_history(&self) -> &VecDeque<StateTransition> {
&self.state_history
}
fn determine_transition(
&self,
from: AppState,
to: AppState,
) -> Result<StateTransition, Box<dyn std::error::Error>> {
match (from, to) {
(AppState::Launching, AppState::Active) => Ok(StateTransition::LaunchToActive),
(AppState::Active, AppState::Background) => Ok(StateTransition::ActiveToBackground),
(AppState::Background, AppState::Active) => Ok(StateTransition::BackgroundToActive),
(AppState::Active, AppState::Inactive) => Ok(StateTransition::ActiveToInactive),
(AppState::Inactive, AppState::Active) => Ok(StateTransition::InactiveToActive),
(AppState::Background, AppState::Suspended) => {
Ok(StateTransition::BackgroundToSuspended)
},
(AppState::Suspended, AppState::Background) => {
Ok(StateTransition::SuspendedToBackground)
},
(_, AppState::Terminating) => Ok(StateTransition::AnyToTerminating),
_ => Err(format!("Invalid state transition from {:?} to {:?}", from, to).into()),
}
}
}
impl Default for AppStateManager {
fn default() -> Self {
Self::new()
}
}