rust_adb/client/
adb_client.rs1use std::net::TcpStream;
2use std::thread;
3use std::thread::JoinHandle;
4
5use crate::adb_host::{
6 connect, read_response_content, read_response_length, AsyncHostCommand, HostConnectionInfo,
7 SyncHostCommand,
8};
9
10use crate::adb_host::host_disconnect::AdbHostDisconnectCommand;
11use crate::adb_host::host_kill::AdbHostKillCommand;
12use crate::adb_host::host_list_device::AdbHostListDevicesCommand;
13use crate::adb_host::host_list_device_l::AdbHostListDeviceLCommand;
14use crate::adb_host::host_start::AdbHostStartCommand;
15use crate::adb_host::host_track_devices::AdbHostTrackDeviceCommand;
16
17use crate::adb_host::host_version::AdbHostVersionCommand;
18use crate::client::device_client::DeviceClientImpl;
19use crate::client::{AdbClient, Device, DeviceService, DeviceWithPath};
20use crate::error::adb::AdbError;
21
22pub struct AdbClientImpl {
23 pub host: String,
24 pub port: i32,
25 pub bin_path: String,
26}
27
28impl AdbClient for AdbClientImpl {
29 fn start_server(&mut self) -> Result<(), AdbError> {
30 let mut command = AdbHostStartCommand::new(&self.host, &self.port, &self.bin_path);
31 command.execute()?;
32 Ok(())
33 }
34
35 fn kill_server(&mut self) -> Result<(), AdbError> {
36 let mut command = AdbHostKillCommand::new(&self.host, &self.port);
37 match command.execute() {
38 Ok(_) => Ok(()),
39 Err(error) => Err(error),
40 }
41 }
42
43 fn restart_server(&mut self) -> Result<(), AdbError> {
44 self.kill_server()?;
45 self.start_server()
46 }
47
48 fn get_connection(&mut self) -> Result<TcpStream, AdbError> {
49 connect(&HostConnectionInfo::new(&self.host, &self.port))
50 }
51
52 fn get_version(&mut self) -> Result<String, AdbError> {
53 let mut command = AdbHostVersionCommand::new(&self.host, &self.port);
54 match command.execute() {
55 Ok(response) => Ok(response.content),
56 Err(error) => Err(error),
57 }
58 }
59
60 fn disconnect(&mut self, host: String, port: i32) -> Result<(), AdbError> {
61 let mut command = AdbHostDisconnectCommand::new(&self.host, &self.port, &host, &port);
62 match command.execute() {
63 Ok(_response) => Ok(()),
64 Err(error) => Err(error),
65 }
66 }
67
68 fn list_devices(&mut self) -> Result<Vec<Device>, AdbError> {
69 let mut command = AdbHostListDevicesCommand::new(&self.host, &self.port);
70 let sync_host_response = command.execute()?;
71 let mut devices = vec![];
72 for line in sync_host_response.content.lines() {
73 let contents: Vec<&str> = line.trim().split_whitespace().collect();
74 if contents.len() >= 2 {
75 devices.push(Device {
76 serial_no: String::from(contents[0]),
77 status: String::from(contents[1]),
78 })
79 }
80 }
81 Ok(devices)
82 }
83
84 fn list_devices_with_path(&mut self) -> Result<Vec<DeviceWithPath>, AdbError> {
85 let mut command = AdbHostListDeviceLCommand::new(&self.host, &self.port);
86 let sync_host_response = command.execute()?;
87 let mut devices = vec![];
88 for line in sync_host_response.content.lines() {
89 let contents: Vec<&str> = line.trim().split_whitespace().collect();
90 if contents.len() >= 6 {
91 devices.push(DeviceWithPath {
92 serial_no: String::from(contents[0]),
93 status: String::from(contents[1]),
94 product: String::from(contents[2]),
95 model: String::from(contents[3]),
96 device: String::from(contents[4]),
97 transport_id: String::from(contents[5]),
98 });
99 continue;
100 }
101 }
102 Ok(devices)
103 }
104
105 fn get_device(&mut self, serial_no: String) -> Result<Box<dyn DeviceService>, AdbError> {
106 Ok(Box::new(DeviceClientImpl::new(&self.host, &self.port, &serial_no)))
107 }
108
109 fn track_devices(
110 &mut self, on_change: fn(Vec<Device>), on_error: fn(AdbError),
111 ) -> Result<JoinHandle<()>, AdbError> {
112 let mut command = AdbHostTrackDeviceCommand::new(&self.host, &self.port);
113 let mut tcp_stream = command.execute()?.tcp_stream;
114 let handler = thread::spawn(move || loop {
115 let length = match read_response_length(&mut tcp_stream) {
116 Ok(length) => length,
117 Err(error) => {
118 on_error(error);
119 return;
120 }
121 };
122
123 let content = match read_response_content(&mut tcp_stream, length) {
124 Ok(content) => content,
125 Err(error) => {
126 on_error(error);
127 return;
128 }
129 };
130 let mut devices = vec![];
131 for line in content.lines() {
132 let contents: Vec<&str> = line.trim().split_whitespace().collect();
133 if contents.len() >= 2 {
134 devices.push(Device {
135 serial_no: String::from(contents[0]),
136 status: String::from(contents[1]),
137 });
138 }
139 }
140 on_change(devices)
141 });
142 Ok(handler)
143 }
144}