adb_kit/
forward.rs

1use crate::device::ADB;
2use crate::error::{ADBError, ADBResult};
3use log::debug;
4use std::process::Command;
5
6impl ADB {
7    /// 将本地端口转发到设备端口
8    pub fn forward(
9        &self,
10        device_id: &str,
11        local_port: u16,
12        device_port: u16,
13    ) -> ADBResult<()> {
14        self.with_retry(|| {
15            let mut cmd = Command::new(&self.config.path);
16
17            // 如果指定了设备 ID 则添加
18            if !device_id.is_empty() {
19                cmd.arg("-s").arg(device_id);
20            }
21
22            let output = cmd
23                .arg("forward")
24                .arg(format!("tcp:{}", local_port))
25                .arg(format!("tcp:{}", device_port))
26                .output()
27                .map_err(|e| ADBError::CommandError(format!("无法执行 ADB forward: {}", e)))?;
28
29            if !output.status.success() {
30                let stderr = String::from_utf8_lossy(&output.stderr);
31                return Err(ADBError::CommandError(format!(
32                    "ADB forward 命令失败: {}",
33                    stderr
34                )));
35            }
36
37            debug!(
38                "端口转发已设置: localhost:{} -> device:{}",
39                local_port, device_port
40            );
41            Ok(())
42        })
43    }
44
45    /// 移除端口转发
46    pub fn remove_forward(&self, local_port: u16) -> ADBResult<()> {
47        self.with_retry(|| {
48            let output = Command::new(&self.config.path)
49                .arg("forward")
50                .arg("--remove")
51                .arg(format!("tcp:{}", local_port))
52                .output()
53                .map_err(|e| {
54                    ADBError::CommandError(format!("无法执行 ADB remove-forward: {}", e))
55                })?;
56
57            if !output.status.success() {
58                let stderr = String::from_utf8_lossy(&output.stderr);
59                return Err(ADBError::CommandError(format!(
60                    "ADB remove-forward 命令失败: {}",
61                    stderr
62                )));
63            }
64
65            debug!("已移除端口转发 localhost:{}", local_port);
66            Ok(())
67        })
68    }
69
70    /// 移除所有端口转发
71    pub fn remove_all_forwards(&self) -> ADBResult<()> {
72        self.with_retry(|| {
73            let output = Command::new(&self.config.path)
74                .arg("forward")
75                .arg("--remove-all")
76                .output()
77                .map_err(|e| {
78                    ADBError::CommandError(format!("无法执行 ADB remove-all-forwards: {}", e))
79                })?;
80
81            if !output.status.success() {
82                let stderr = String::from_utf8_lossy(&output.stderr);
83                return Err(ADBError::CommandError(format!(
84                    "ADB remove-all-forwards 命令失败: {}",
85                    stderr
86                )));
87            }
88
89            debug!("已移除所有端口转发");
90            Ok(())
91        })
92    }
93
94    /// 列出所有端口转发
95    pub fn list_forwards(&self) -> ADBResult<String> {
96        self.with_retry(|| {
97            let output = Command::new(&self.config.path)
98                .arg("forward")
99                .arg("--list")
100                .output()
101                .map_err(|e| {
102                    ADBError::CommandError(format!("无法执行 ADB list-forwards: {}", e))
103                })?;
104
105            if !output.status.success() {
106                let stderr = String::from_utf8_lossy(&output.stderr);
107                return Err(ADBError::CommandError(format!(
108                    "ADB list-forwards 命令失败: {}",
109                    stderr
110                )));
111            }
112
113            let stdout = String::from_utf8_lossy(&output.stdout).to_string();
114            Ok(stdout)
115        })
116    }
117
118    /// 反向端口转发(设备到主机)
119    pub fn reverse(
120        &self,
121        device_id: &str,
122        remote_port: u16,
123        local_port: u16,
124    ) -> ADBResult<()> {
125        self.with_retry(|| {
126            let mut cmd = Command::new(&self.config.path);
127
128            // 如果指定了设备 ID 则添加
129            if !device_id.is_empty() {
130                cmd.arg("-s").arg(device_id);
131            }
132
133            let output = cmd
134                .arg("reverse")
135                .arg(format!("tcp:{}", remote_port))
136                .arg(format!("tcp:{}", local_port))
137                .output()
138                .map_err(|e| ADBError::CommandError(format!("无法执行 ADB reverse: {}", e)))?;
139
140            if !output.status.success() {
141                let stderr = String::from_utf8_lossy(&output.stderr);
142                return Err(ADBError::CommandError(format!(
143                    "ADB reverse 命令失败: {}",
144                    stderr
145                )));
146            }
147
148            debug!(
149                "反向端口转发已设置: device:{} -> localhost:{}",
150                remote_port, local_port
151            );
152            Ok(())
153        })
154    }
155
156    /// 移除反向端口转发
157    pub fn remove_reverse(&self, device_id: &str, remote_port: u16) -> ADBResult<()> {
158        self.with_retry(|| {
159            let mut cmd = Command::new(&self.config.path);
160
161            // 如果指定了设备 ID 则添加
162            if !device_id.is_empty() {
163                cmd.arg("-s").arg(device_id);
164            }
165
166            let output = cmd
167                .arg("reverse")
168                .arg("--remove")
169                .arg(format!("tcp:{}", remote_port))
170                .output()
171                .map_err(|e| {
172                    ADBError::CommandError(format!("无法执行 ADB remove-reverse: {}", e))
173                })?;
174
175            if !output.status.success() {
176                let stderr = String::from_utf8_lossy(&output.stderr);
177                return Err(ADBError::CommandError(format!(
178                    "ADB remove-reverse 命令失败: {}",
179                    stderr
180                )));
181            }
182
183            debug!("已移除反向端口转发 device:{}", remote_port);
184            Ok(())
185        })
186    }
187
188    /// 移除所有反向端口转发
189    pub fn remove_all_reverses(&self, device_id: &str) -> ADBResult<()> {
190        self.with_retry(|| {
191            let mut cmd = Command::new(&self.config.path);
192
193            // 如果指定了设备 ID 则添加
194            if !device_id.is_empty() {
195                cmd.arg("-s").arg(device_id);
196            }
197
198            let output = cmd
199                .arg("reverse")
200                .arg("--remove-all")
201                .output()
202                .map_err(|e| {
203                    ADBError::CommandError(format!("无法执行 ADB remove-all-reverses: {}", e))
204                })?;
205
206            if !output.status.success() {
207                let stderr = String::from_utf8_lossy(&output.stderr);
208                return Err(ADBError::CommandError(format!(
209                    "ADB remove-all-reverses 命令失败: {}",
210                    stderr
211                )));
212            }
213
214            debug!("已移除设备上所有反向端口转发");
215            Ok(())
216        })
217    }
218}