//! Linux ARM64 设备后端实现 //! //! 支持 Linux ARM64 平台的设备操作,包括显示信息、背光控制、防息屏等功能。 use crate::core::message::{DeviceCapability, DeviceCommand, DeviceResponse, PixelFormat}; use crate::plugins::device::backend::DeviceBackend; use anyhow::Result; use std::fs; use std::process::{Child, Command, Stdio}; /// Linux ARM64 设备后端 /// /// 通过 sysfs 和 systemd-inhibit 实现设备控制。 pub struct LinuxArm64Backend { /// systemd-inhibit 子进程(用于防息屏) wake_lock_child: Option, /// 显示宽度 display_width: u32, /// 显示高度 display_height: u32, /// 背光状态 backlight_enabled: bool, } impl LinuxArm64Backend { /// 创建新的 Linux ARM64 后端实例 pub fn new() -> Self { Self { wake_lock_child: None, display_width: 1920, // 默认分辨率 display_height: 1080, backlight_enabled: true, } } /// 读取 framebuffer 分辨率 fn read_framebuffer_resolution(&mut self) -> Result<()> { // 尝试从 /sys/class/graphics/fb0/virtual_size 读取分辨率 if let Ok(content) = fs::read_to_string("/sys/class/graphics/fb0/virtual_size") { let parts: Vec<&str> = content.trim().split(',').collect(); if parts.len() == 2 { if let (Ok(width), Ok(height)) = (parts[0].parse(), parts[1].parse()) { self.display_width = width; self.display_height = height; return Ok(()); } } } // 如果读取失败,使用默认值(已在 new() 中设置) Ok(()) } /// 启动防息屏(systemd-inhibit) fn start_sleep_inhibit(&mut self) -> Result<()> { if self.wake_lock_child.is_some() { return Ok(()); } match Command::new("systemd-inhibit") .arg("--what=idle:sleep") .arg("--mode=block") .arg("--who=ShowenV2") .arg("--why=Device operation in progress") .arg("sleep") .arg("infinity") .stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::null()) .spawn() { Ok(child) => { self.wake_lock_child = Some(child); Ok(()) } Err(e) => Err(anyhow::anyhow!("Failed to start systemd-inhibit: {}", e)), } } /// 停止防息屏 fn stop_sleep_inhibit(&mut self) -> Result<()> { if let Some(mut child) = self.wake_lock_child.take() { child.kill()?; child.wait()?; } Ok(()) } /// 设置背光状态 fn set_backlight(&mut self, enabled: bool) -> Result<()> { self.backlight_enabled = enabled; // 尝试写入 /sys/class/backlight/*/brightness // 首先查找 backlight 设备 if let Ok(entries) = fs::read_dir("/sys/class/backlight") { for entry in entries.flatten() { let brightness_path = entry.path().join("brightness"); let max_brightness_path = entry.path().join("max_brightness"); // 读取最大亮度 if let Ok(max_str) = fs::read_to_string(&max_brightness_path) { if let Ok(max_brightness) = max_str.trim().parse::() { // 设置亮度:开启时设为最大值,关闭时设为 0 let value = if enabled { max_brightness } else { 0 }; if fs::write(&brightness_path, value.to_string()).is_ok() { return Ok(()); } } } } } // 如果没有找到 backlight 设备,返回成功(某些设备可能不支持) Ok(()) } } impl DeviceBackend for LinuxArm64Backend { fn name(&self) -> &str { "linux-arm64" } fn init(&mut self, _config: &serde_json::Value) -> Result<()> { // 读取 framebuffer 分辨率 self.read_framebuffer_resolution()?; Ok(()) } fn capabilities(&self) -> Vec { vec![ DeviceCapability::Display, DeviceCapability::Backlight, DeviceCapability::Framebuffer, ] } fn handle_command(&mut self, cmd: DeviceCommand) -> Result { match cmd { DeviceCommand::GetDisplayInfo => Ok(DeviceResponse::DisplayInfo { width: self.display_width, height: self.display_height, format: PixelFormat::RGB888, }), DeviceCommand::SetSleepInhibit(enable) => { if enable { self.start_sleep_inhibit()?; } else { self.stop_sleep_inhibit()?; } Ok(DeviceResponse::Ok) } DeviceCommand::SetBacklight(enabled) => { self.set_backlight(enabled)?; Ok(DeviceResponse::Ok) } _ => Ok(DeviceResponse::Error("Not implemented".to_string())), } } fn shutdown(&mut self) -> Result<()> { // 清理 wake_lock_child self.stop_sleep_inhibit()?; Ok(()) } }