rust_adb/client/
adb_client.rs

1use 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}