rust_adb/client/
device_client.rs

1use crate::adb_device::device_get_features::DeviceGetFeaturesCommand;
2use crate::adb_device::device_get_packages::DeviceGetPackagesCommand;
3use crate::adb_device::device_get_properties::DeviceGetPropertiesCommand;
4use crate::adb_device::device_logcat::{read_next_entry, DeviceLogcatCommand};
5use crate::adb_device::device_shell_async::DeviceAsyncShellCommand;
6use crate::adb_device::device_shell_sync::DeviceSyncShellCommand;
7use crate::adb_device::{AsyncDeviceCommand, SyncDeviceCommand};
8use crate::client::{DeviceService, LogEntry};
9use crate::error::adb::AdbError;
10use std::collections::HashMap;
11use std::fs::File;
12use std::net::TcpStream;
13use std::thread;
14use std::thread::JoinHandle;
15
16pub struct DeviceClientImpl {
17    pub host: String,
18    pub port: i32,
19    pub serial_no: String,
20}
21
22impl DeviceClientImpl {
23    pub fn new(host: &String, port: &i32, serial_no: &String) -> DeviceClientImpl {
24        DeviceClientImpl {
25            host: host.clone(),
26            port: port.clone(),
27            serial_no: serial_no.clone(),
28        }
29    }
30}
31
32impl DeviceService for DeviceClientImpl {
33    fn push(&mut self, _content: File, _path: String, _mode: i32) -> Result<String, AdbError> {
34        todo!()
35    }
36
37    fn shell_sync(&mut self, command: &String) -> Result<String, AdbError> {
38        let mut command =
39            DeviceSyncShellCommand::new0(&self.host, &self.port, &self.serial_no, &command);
40        match command.execute() {
41            Ok(response) => Ok(response.content),
42            Err(error) => Err(error),
43        }
44    }
45
46    fn shell_async(&mut self, command: &String) -> Result<TcpStream, AdbError> {
47        let mut command =
48            DeviceAsyncShellCommand::new0(&self.host, &self.port, &self.serial_no, &command);
49        match command.execute() {
50            Ok(response) => Ok(response.tcp_stream),
51            Err(error) => Err(error),
52        }
53    }
54
55    fn get_packages(&mut self, params: &String) -> Result<Vec<String>, AdbError> {
56        let mut command =
57            DeviceGetPackagesCommand::new(&self.host, &self.port, &self.serial_no, &params);
58        let content = match command.execute() {
59            Ok(response) => response.content,
60            Err(error) => {
61                return Err(error);
62            }
63        };
64        let mut packages = vec![];
65        let lines: Vec<&str> = content.split_whitespace().collect();
66        for line in lines {
67            if !line.contains("package:") {
68                continue;
69            }
70            let package = line.replace("package:", "");
71            packages.push(package)
72        }
73        Ok(packages)
74    }
75
76    fn get_features(&mut self) -> Result<HashMap<String, String>, AdbError> {
77        let mut command = DeviceGetFeaturesCommand::new(&self.host, &self.port, &self.serial_no);
78        let content = match command.execute() {
79            Ok(response) => response.content.clone(),
80            Err(error) => {
81                return Err(error);
82            }
83        };
84        let mut features = HashMap::new();
85        let lines: Vec<&str> = content.split("\n").collect();
86        for line in lines {
87            let replace_item = line.replace("feature:", "");
88            let line_item: Vec<&str> = replace_item.trim().split("=").collect();
89            if line_item.len() < 2 {
90                features.insert(String::from(line_item[0]), String::from("true"));
91                continue;
92            }
93            features.insert(String::from(line_item[0]), String::from(line_item[1]));
94        }
95        Ok(features)
96    }
97
98    fn get_properties(&mut self, params: &String) -> Result<HashMap<String, String>, AdbError> {
99        let mut command =
100            DeviceGetPropertiesCommand::new(&self.host, &self.port, &self.serial_no, &params);
101        let content = match command.execute() {
102            Ok(response) => response.content.clone(),
103            Err(error) => {
104                return Err(error);
105            }
106        };
107        let mut properties = HashMap::new();
108        let lines: Vec<&str> = content.split("\n").collect();
109        for line in lines {
110            let replace_item = line.replace("[", "").replace("]", "");
111            let line_item: Vec<&str> = replace_item.trim().split(":").collect();
112            if line_item.len() < 2 {
113                continue;
114            }
115            properties.insert(String::from(line_item[0].trim()), String::from(line_item[1].trim()));
116        }
117        Ok(properties)
118    }
119
120    fn logcat(
121        &mut self, params: &String, consumer: fn(LogEntry), error_handler: fn(AdbError),
122    ) -> Result<JoinHandle<()>, AdbError> {
123        let mut command =
124            DeviceLogcatCommand::new(&self.host, &self.port, &self.serial_no, &params);
125        let mut tcp_stream = match command.execute() {
126            Ok(response) => response.tcp_stream,
127            Err(error) => {
128                return Err(error);
129            }
130        };
131        let handler = thread::spawn(move || loop {
132            let log_entry = match read_next_entry(&mut tcp_stream) {
133                Ok(response) => response,
134                Err(error) => {
135                    error_handler(error);
136                    break;
137                }
138            };
139            consumer(log_entry)
140        });
141        Ok(handler)
142    }
143}