Skip to main content

aios_collector/
system_collector.rs

1//! 系统状态采集器
2//!
3//! "how" — 如何获取设备层状态信息。
4//!
5//! 采集: 电池、网络、铃声模式、位置、耳机/蓝牙。
6//! Linux 桌面环境下使用 fallback 值。
7
8use aios_spec::{LocationType, NetworkType, RingerMode, SystemStateEvent};
9
10/// 系统状态采集器
11pub struct SystemStateCollector;
12
13impl SystemStateCollector {
14    /// 获取当前系统状态快照
15    ///
16    /// 在 Android (daemon) 上:
17    /// - 电池: 读 /sys/class/power_supply/battery/capacity
18    /// - 网络: 读 /sys/class/net/*/operstate
19    /// - 位置: 通过 LocationManager (需要 Kotlin 端配合)
20    ///
21    /// 在 Linux 桌面上: 返回 fallback 值
22    pub fn snapshot(timestamp_ms: i64) -> SystemStateEvent {
23        SystemStateEvent {
24            timestamp_ms,
25            battery_pct: Self::read_battery(),
26            is_charging: Self::read_charging(),
27            network: Self::detect_network(),
28            ringer_mode: RingerMode::Normal,
29            location_type: LocationType::Unknown,
30            headphone_connected: false,
31            bluetooth_connected: false,
32        }
33    }
34
35    /// 读取电量百分比
36    fn read_battery() -> Option<u8> {
37        // Android: /sys/class/power_supply/battery/capacity
38        let paths = [
39            "/sys/class/power_supply/battery/capacity",
40            "/sys/class/power_supply/BAT0/capacity",
41            "/sys/class/power_supply/BAT1/capacity",
42        ];
43
44        for path in &paths {
45            if let Ok(content) = std::fs::read_to_string(path) {
46                if let Ok(pct) = content.trim().parse::<u8>() {
47                    return Some(pct);
48                }
49            }
50        }
51        None
52    }
53
54    /// 读取充电状态
55    fn read_charging() -> bool {
56        let paths = [
57            "/sys/class/power_supply/battery/status",
58            "/sys/class/power_supply/BAT0/status",
59        ];
60
61        for path in &paths {
62            if let Ok(content) = std::fs::read_to_string(path) {
63                return content.trim().to_lowercase().contains("charging");
64            }
65        }
66        false
67    }
68
69    /// 检测网络类型
70    fn detect_network() -> NetworkType {
71        // 检查 /sys/class/net/ 下各接口的状态
72        if let Ok(entries) = std::fs::read_dir("/sys/class/net") {
73            for entry in entries.flatten() {
74                let name = entry.file_name();
75                let name_str = name.to_string_lossy();
76                let operstate_path = entry.path().join("operstate");
77
78                if let Ok(state) = std::fs::read_to_string(&operstate_path) {
79                    let up = state.trim() == "up";
80
81                    if up && (name_str.starts_with("wlan") || name_str == "wlan0") {
82                        return NetworkType::Wifi;
83                    }
84                    if up && (name_str.starts_with("rmnet") || name_str.starts_with("wwan")) {
85                        return NetworkType::Cellular;
86                    }
87                }
88            }
89
90            // 如果以太网接口是 up 的
91            if std::fs::read_to_string("/sys/class/net/eth0/operstate")
92                .map(|s| s.trim() == "up")
93                .unwrap_or(false)
94            {
95                return NetworkType::Wifi; // 有线也归类为 WiFi (有网络)
96            }
97        }
98
99        NetworkType::Unknown
100    }
101}