adb_kit/
device.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::fmt;
4use std::sync::{Arc, Mutex};
5
6use crate::config::ADBConfig;
7
8/// ADB 设备状态枚举
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub enum DeviceStatus {
11    Online,
12    Offline,
13    Unauthorized,
14    Recovery,
15    Sideload,
16    Bootloader,
17    Other(String),
18}
19
20impl fmt::Display for DeviceStatus {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            DeviceStatus::Online => write!(f, "online"),
24            DeviceStatus::Offline => write!(f, "offline"),
25            DeviceStatus::Unauthorized => write!(f, "unauthorized"),
26            DeviceStatus::Recovery => write!(f, "recovery"),
27            DeviceStatus::Sideload => write!(f, "sideload"),
28            DeviceStatus::Bootloader => write!(f, "bootloader"),
29            DeviceStatus::Other(s) => write!(f, "{}", s),
30        }
31    }
32}
33
34impl From<&str> for DeviceStatus {
35    fn from(s: &str) -> Self {
36        match s.to_lowercase().as_str() {
37            "device" | "online" => DeviceStatus::Online,
38            "offline" => DeviceStatus::Offline,
39            "unauthorized" => DeviceStatus::Unauthorized,
40            "recovery" => DeviceStatus::Recovery,
41            "sideload" => DeviceStatus::Sideload,
42            "bootloader" | "fastboot" => DeviceStatus::Bootloader,
43            _ => DeviceStatus::Other(s.to_string()),
44        }
45    }
46}
47
48/// ADB 设备结构体
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct ADBDevice {
51    pub id: String,
52    pub name: String,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub model: Option<String>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub product: Option<String>,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub transport_id: Option<String>,
59    pub status: DeviceStatus,
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub properties: Option<HashMap<String, String>>,
62}
63
64impl ADBDevice {
65    /// 创建新设备实例
66    pub fn new(id: &str, status: impl Into<DeviceStatus>) -> Self {
67        Self {
68            id: id.to_string(),
69            name: format!("Device {}", id),
70            model: None,
71            product: None,
72            transport_id: None,
73            status: status.into(),
74            properties: None,
75        }
76    }
77
78    /// 检查设备是否在线
79    pub fn is_online(&self) -> bool {
80        self.status == DeviceStatus::Online
81    }
82
83    /// 设置设备名称
84    pub fn with_name(mut self, name: &str) -> Self {
85        self.name = name.to_string();
86        self
87    }
88
89    /// 设置设备模型
90    pub fn with_model(mut self, model: &str) -> Self {
91        self.model = Some(model.to_string());
92        self
93    }
94
95    /// 设置设备产品信息
96    pub fn with_product(mut self, product: &str) -> Self {
97        self.product = Some(product.to_string());
98        self
99    }
100
101    /// 设置传输 ID
102    pub fn with_transport_id(mut self, transport_id: &str) -> Self {
103        self.transport_id = Some(transport_id.to_string());
104        self
105    }
106
107    /// 添加设备属性
108    pub fn add_property(mut self, key: &str, value: &str) -> Self {
109        if self.properties.is_none() {
110            self.properties = Some(HashMap::new());
111        }
112
113        if let Some(props) = &mut self.properties {
114            props.insert(key.to_string(), value.to_string());
115        }
116
117        self
118    }
119}
120
121/// ADB 连接池类型
122type DevicePool = HashMap<String, Arc<Mutex<std::process::Child>>>;
123
124/// ADB 主结构体
125#[derive(Clone, Debug)]
126pub struct ADB {
127    pub config: ADBConfig,
128    pub(crate) connections: Arc<Mutex<DevicePool>>,
129}
130
131impl ADB {
132    /// 创建新的 ADB 实例
133    pub fn new(config: Option<ADBConfig>) -> Self {
134        Self {
135            config: config.unwrap_or_default(),
136            connections: Arc::new(Mutex::new(HashMap::new())),
137        }
138    }
139
140    /// 获取 ADB 路径
141    pub fn adb_path(&self) -> &std::path::PathBuf {
142        &self.config.path
143    }
144}