rust_adb/adb_device/
mod.rs

1use crate::adb_host::{
2    read_response_content, read_response_length, read_response_status, write_command,
3    AsyncHostCommand,
4};
5use std::io::Read;
6use std::net::TcpStream;
7use std::time::Duration;
8
9use crate::adb_host::host_transport::AdbHostTransportCommand;
10use crate::adb_host::HostConnectionInfo;
11use crate::error::adb::AdbError;
12
13pub mod device_get_features;
14pub mod device_get_packages;
15pub mod device_get_properties;
16pub mod device_logcat;
17pub mod device_reboot;
18pub mod device_remount;
19pub mod device_root;
20pub mod device_shell_async;
21pub mod device_shell_sync;
22
23pub trait SyncDeviceCommand {
24    fn execute(&mut self) -> Result<SyncDeviceProtocol, AdbError>;
25}
26
27pub trait AsyncDeviceCommand {
28    fn execute(&mut self) -> Result<AsyncDeviceProtocol, AdbError>;
29}
30
31pub struct SyncDeviceProtocol {
32    pub length: usize,
33    pub content: String,
34}
35
36pub struct AsyncDeviceProtocol {
37    pub tcp_stream: TcpStream,
38}
39
40pub struct DeviceConnectionInfo {
41    pub host: String,
42    pub port: i32,
43    pub serial_no: String,
44    pub read_timeout: Option<Duration>,
45    pub write_timeout: Option<Duration>,
46}
47
48impl Clone for DeviceConnectionInfo {
49    fn clone(&self) -> Self {
50        DeviceConnectionInfo {
51            host: self.host.clone(),
52            port: self.port.clone(),
53            serial_no: self.serial_no.clone(),
54            read_timeout: self.read_timeout.clone(),
55            write_timeout: self.write_timeout.clone(),
56        }
57    }
58}
59
60impl DeviceConnectionInfo {
61    pub fn new(host: &String, port: &i32, serial_no: &String) -> DeviceConnectionInfo {
62        DeviceConnectionInfo {
63            host: host.clone(),
64            port: port.clone(),
65            serial_no: serial_no.clone(),
66            read_timeout: Option::from(Duration::from_millis(1000)),
67            write_timeout: Option::from(Duration::from_millis(1000)),
68        }
69    }
70
71    pub fn host_connection_info(&self) -> HostConnectionInfo {
72        HostConnectionInfo {
73            host: self.host.clone(),
74            port: self.port.clone(),
75            read_timeout: self.read_timeout.clone(),
76            write_timeout: self.write_timeout.clone(),
77        }
78    }
79}
80
81fn device_connection(device_connection_info: &DeviceConnectionInfo) -> Result<TcpStream, AdbError> {
82    let host_connection_info = device_connection_info.host_connection_info();
83    let mut command =
84        AdbHostTransportCommand::new(&host_connection_info, &device_connection_info.serial_no);
85    let async_protocol = command.execute()?;
86    Ok(async_protocol.tcp_stream)
87}
88
89pub fn exec_device_command_sync(
90    mut tcp_stream: TcpStream, command: String,
91) -> Result<AsyncDeviceProtocol, AdbError> {
92    write_command(&mut tcp_stream, &command)?;
93
94    let status = read_response_status(&mut tcp_stream)?;
95
96    if status == "OKAY" {
97        return Ok(AsyncDeviceProtocol { tcp_stream });
98    }
99
100    if status == "FAIL" {
101        let length = read_response_length(&mut tcp_stream)?;
102
103        let content = read_response_content(&mut tcp_stream, length)?;
104        return Err(AdbError::ResponseStatusError { content });
105    }
106
107    Err(AdbError::ResponseStatusError {
108        content: String::from("unknown response status ") + &*status,
109    })
110}
111
112pub fn exec_device_command(
113    tcp_stream: &mut TcpStream, command: String,
114) -> Result<SyncDeviceProtocol, AdbError> {
115    write_command(tcp_stream, &command)?;
116
117    let status = read_response_status(tcp_stream)?;
118
119    if status == "OKAY" {
120        let content = read_response_all_content(tcp_stream)?;
121
122        return Ok(SyncDeviceProtocol {
123            length: content.len(),
124            content,
125        });
126    }
127
128    if status == "FAIL" {
129        let length = read_response_length(tcp_stream)?;
130
131        let content = read_response_content(tcp_stream, length)?;
132        return Err(AdbError::ResponseStatusError { content });
133    }
134
135    Err(AdbError::ResponseStatusError {
136        content: String::from("unknown response status ") + &*status,
137    })
138}
139
140pub fn read_response_all_content(tcp_stream: &mut TcpStream) -> Result<String, AdbError> {
141    let mut response_content = vec![];
142    match tcp_stream.read_to_end(&mut response_content) {
143        Ok(_) => {}
144        Err(error) => {
145            return Err(AdbError::TcpReadError {
146                source: Box::new(error),
147            });
148        }
149    };
150
151    match String::from_utf8(Vec::from(response_content)) {
152        Ok(content_string) => Ok(content_string),
153        Err(error) => {
154            return Err(AdbError::ParseResponseError {
155                source: Box::new(error),
156            });
157        }
158    }
159}