1use serde::{Deserialize, Serialize};
7use std::collections::{HashMap, VecDeque};
8use std::time::Instant;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum AppState {
13 Launching,
15 Active,
17 Background,
19 Inactive,
21 Suspended,
23 Terminating,
25 Unknown,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
31pub enum StateTransition {
32 LaunchToActive,
33 ActiveToBackground,
34 BackgroundToActive,
35 ActiveToInactive,
36 InactiveToActive,
37 BackgroundToSuspended,
38 SuspendedToBackground,
39 AnyToTerminating,
40}
41
42#[derive(Debug, Clone)]
44pub struct StateTransitionEvent {
45 pub from_state: AppState,
46 pub to_state: AppState,
47 pub transition: StateTransition,
48 pub timestamp: Instant,
49 pub reason: TransitionReason,
50 pub context: TransitionContext,
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
55pub enum TransitionReason {
56 UserAction,
57 SystemRequest,
58 LowMemory,
59 LowBattery,
60 ThermalPressure,
61 NetworkInterruption,
62 Timeout,
63 Error,
64 SystemSuspend,
65 SystemResume,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct TransitionContext {
71 pub available_memory_mb: usize,
73 pub battery_level_percent: u8,
75 pub cpu_temperature_celsius: f32,
77 pub network_connected: bool,
79 pub active_background_tasks: usize,
81 pub time_since_user_interaction_seconds: u64,
83 pub foreground_duration_seconds: u64,
85 pub background_duration_seconds: u64,
87 pub system_pressure: SystemPressureIndicators,
89 pub resource_usage: ResourceUsageSnapshot,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct SystemPressureIndicators {
96 pub memory_pressure: crate::lifecycle::config::MemoryPressureLevel,
98 pub thermal_state: crate::lifecycle::config::ThermalLevel,
100 pub battery_state: crate::battery::BatteryLevel,
102 pub network_quality: NetworkQuality,
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
108pub enum NetworkQuality {
109 Excellent,
110 Good,
111 Fair,
112 Poor,
113 Disconnected,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct ResourceUsageSnapshot {
119 pub cpu_usage_percent: f32,
121 pub memory_usage_mb: usize,
123 pub gpu_usage_percent: Option<f32>,
125 pub network_usage_mbps: f32,
127 pub storage_io_mbps: f32,
129 pub active_models: usize,
131 pub inference_queue_size: usize,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct AppCheckpoint {
138 pub app_state: AppState,
140 pub timestamp: u64, pub model_states: Vec<ModelState>,
144 pub cache_states: HashMap<String, CacheState>,
146 pub user_session: UserSessionState,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct ModelState {
153 pub model_id: String,
155 pub load_state: ModelLoadState,
157 pub configuration: ModelConfiguration,
159 pub performance_metrics: ModelPerformanceMetrics,
161 pub last_access_timestamp: u64,
163 pub usage_count: usize,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
169pub enum ModelLoadState {
170 Unloaded,
171 Loading,
172 Loaded,
173 Error,
174 Cached,
175 Compressed,
176 Offloaded,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct CacheState {
182 pub size_bytes: usize,
184 pub item_count: usize,
186 pub last_access_timestamp: u64,
188 pub hit_rate_percent: f32,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct ModelConfiguration {
195 pub precision: ModelPrecision,
197 pub optimization_level: OptimizationLevel,
199 pub backend: ModelBackend,
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
205pub enum ModelPrecision {
206 FP32,
207 FP16,
208 INT8,
209 INT4,
210 Dynamic,
211}
212
213#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
215pub enum OptimizationLevel {
216 None,
217 Basic,
218 Aggressive,
219 UltraLowMemory,
220}
221
222#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
224pub enum ModelBackend {
225 CPU,
226 CoreML,
227 NNAPI,
228 Metal,
229 Vulkan,
230 Custom,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct ModelPerformanceMetrics {
236 pub avg_inference_time_ms: f32,
238 pub memory_usage_mb: usize,
240 pub throughput_per_second: f32,
242 pub error_rate_percent: f32,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
248pub struct TaskState {
249 pub task_id: String,
251 pub task_type: crate::lifecycle::config::TaskType,
253 pub status: LifecycleTaskStatus,
255 pub priority: crate::lifecycle::config::TaskPriority,
257 pub progress_percent: u8,
259 pub estimated_completion_seconds: Option<u64>,
261}
262
263#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
265pub enum LifecycleTaskStatus {
266 Pending,
267 Running,
268 Paused,
269 Completed,
270 Failed,
271 Cancelled,
272}
273
274#[derive(Debug, Clone, Serialize, Deserialize)]
276pub struct UserSessionState {
277 pub session_start_timestamp: u64,
279 pub total_interaction_time_seconds: u64,
281 pub recent_interactions: Vec<UserInteraction>,
283 pub session_stats: SessionStatistics,
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
289pub struct UserInteraction {
290 pub timestamp: u64,
292 pub interaction_type: InteractionType,
294 pub outcome: InteractionOutcome,
296 pub duration_ms: u64,
298}
299
300#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
302pub enum InteractionType {
303 Touch,
304 Voice,
305 Gesture,
306 TextInput,
307 ModelInference,
308 Navigation,
309 Settings,
310}
311
312#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
314pub enum InteractionOutcome {
315 Success,
316 Failure,
317 Cancelled,
318 Timeout,
319 Error,
320}
321
322#[derive(Debug, Clone, Serialize, Deserialize)]
324pub struct SessionStatistics {
325 pub total_inferences: usize,
327 pub total_models_loaded: usize,
329 pub total_background_tasks: usize,
331 pub avg_response_time_ms: f32,
333 pub error_count: usize,
335}
336
337#[derive(Debug, Clone, Serialize, Deserialize)]
339pub struct SystemContext {
340 pub timestamp: u64,
342 pub device_info: SystemDeviceInfo,
344 pub resource_availability: ResourceAvailability,
346 pub network_status: NetworkStatus,
348 pub power_status: PowerStatus,
350 pub thermal_status: ThermalStatus,
352 pub active_processes: ProcessInfo,
354 pub system_load: SystemLoad,
356}
357
358#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct SystemDeviceInfo {
361 pub device_model: String,
363 pub os_version: String,
365 pub cpu_cores: usize,
367 pub total_ram_mb: usize,
369 pub available_storage_mb: usize,
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
375pub struct ResourceAvailability {
376 pub available_cpu_percent: f32,
378 pub available_memory_mb: usize,
380 pub available_gpu_percent: Option<f32>,
382 pub available_network_mbps: f32,
384}
385
386#[derive(Debug, Clone, Serialize, Deserialize)]
388pub struct NetworkStatus {
389 pub connected: bool,
391 pub connection_type: NetworkConnectionType,
393 pub signal_strength_percent: u8,
395 pub quality: NetworkQuality,
397 pub data_usage_mb: f32,
399}
400
401#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
403pub enum NetworkConnectionType {
404 WiFi,
405 Cellular,
406 Ethernet,
407 Bluetooth,
408 Unknown,
409}
410
411#[derive(Debug, Clone, Serialize, Deserialize)]
413pub struct PowerStatus {
414 pub battery_level_percent: u8,
416 pub charging_status: ChargingStatus,
418 pub power_save_mode: bool,
420 pub estimated_battery_life_minutes: Option<u32>,
422}
423
424#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
426pub enum ChargingStatus {
427 Charging,
428 Discharging,
429 Full,
430 NotCharging,
431 Unknown,
432}
433
434#[derive(Debug, Clone, Serialize, Deserialize)]
436pub struct ThermalStatus {
437 pub cpu_temperature_celsius: f32,
439 pub gpu_temperature_celsius: Option<f32>,
441 pub thermal_state: crate::lifecycle::config::ThermalLevel,
443 pub throttling_active: bool,
445}
446
447#[derive(Debug, Clone, Serialize, Deserialize)]
449pub struct ProcessInfo {
450 pub total_processes: usize,
452 pub active_processes: usize,
454 pub background_processes: usize,
456 pub process_memory_usage_mb: usize,
458}
459
460#[derive(Debug, Clone, Serialize, Deserialize)]
462pub struct SystemLoad {
463 pub load_1min: f32,
465 pub load_5min: f32,
467 pub load_15min: f32,
469 pub cpu_utilization_percent: f32,
471 pub memory_utilization_percent: f32,
473}
474
475pub struct AppStateManager {
477 current_state: AppState,
478 previous_state: AppState,
479 state_history: VecDeque<StateTransition>,
480 state_listeners: Vec<Box<dyn StateListener>>,
481 transition_handlers: HashMap<StateTransition, Box<dyn TransitionHandler>>,
482}
483
484pub trait StateListener: Send + Sync {
486 fn on_state_change(&self, event: &StateTransitionEvent);
487}
488
489pub trait TransitionHandler: Send + Sync {
491 fn handle_transition(
492 &self,
493 event: &StateTransitionEvent,
494 ) -> Result<(), Box<dyn std::error::Error>>;
495}
496
497impl AppStateManager {
498 pub fn new() -> Self {
500 Self {
501 current_state: AppState::Unknown,
502 previous_state: AppState::Unknown,
503 state_history: VecDeque::new(),
504 state_listeners: Vec::new(),
505 transition_handlers: HashMap::new(),
506 }
507 }
508
509 pub fn current_state(&self) -> AppState {
511 self.current_state
512 }
513
514 pub fn previous_state(&self) -> AppState {
516 self.previous_state
517 }
518
519 pub fn transition_to_state(
521 &mut self,
522 new_state: AppState,
523 reason: TransitionReason,
524 context: TransitionContext,
525 ) -> Result<(), Box<dyn std::error::Error>> {
526 let transition = self.determine_transition(self.current_state, new_state)?;
527
528 let event = StateTransitionEvent {
529 from_state: self.current_state,
530 to_state: new_state,
531 transition,
532 timestamp: Instant::now(),
533 reason,
534 context,
535 };
536
537 if let Some(handler) = self.transition_handlers.get(&transition) {
539 handler.handle_transition(&event)?;
540 }
541
542 self.previous_state = self.current_state;
544 self.current_state = new_state;
545 self.state_history.push_back(transition);
546
547 if self.state_history.len() > 100 {
549 self.state_history.pop_front();
550 }
551
552 for listener in &self.state_listeners {
554 listener.on_state_change(&event);
555 }
556
557 Ok(())
558 }
559
560 pub fn add_state_listener(&mut self, listener: Box<dyn StateListener>) {
562 self.state_listeners.push(listener);
563 }
564
565 pub fn add_transition_handler(
567 &mut self,
568 transition: StateTransition,
569 handler: Box<dyn TransitionHandler>,
570 ) {
571 self.transition_handlers.insert(transition, handler);
572 }
573
574 pub fn get_state_history(&self) -> &VecDeque<StateTransition> {
576 &self.state_history
577 }
578
579 fn determine_transition(
581 &self,
582 from: AppState,
583 to: AppState,
584 ) -> Result<StateTransition, Box<dyn std::error::Error>> {
585 match (from, to) {
586 (AppState::Launching, AppState::Active) => Ok(StateTransition::LaunchToActive),
587 (AppState::Active, AppState::Background) => Ok(StateTransition::ActiveToBackground),
588 (AppState::Background, AppState::Active) => Ok(StateTransition::BackgroundToActive),
589 (AppState::Active, AppState::Inactive) => Ok(StateTransition::ActiveToInactive),
590 (AppState::Inactive, AppState::Active) => Ok(StateTransition::InactiveToActive),
591 (AppState::Background, AppState::Suspended) => {
592 Ok(StateTransition::BackgroundToSuspended)
593 },
594 (AppState::Suspended, AppState::Background) => {
595 Ok(StateTransition::SuspendedToBackground)
596 },
597 (_, AppState::Terminating) => Ok(StateTransition::AnyToTerminating),
598 _ => Err(format!("Invalid state transition from {:?} to {:?}", from, to).into()),
599 }
600 }
601}
602
603impl Default for AppStateManager {
604 fn default() -> Self {
605 Self::new()
606 }
607}