From 66ebc8a030503fda99bfbfdeb6bffc2faf0d7110 Mon Sep 17 00:00:00 2001 From: 0vercl0k <1476421+0vercl0k@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:20:51 -0700 Subject: [PATCH 01/11] Reword logic in `LogFilter::write` to avoid cloning the internal buffer --- .../src/server_device/commands/logcat.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/adb_client/src/server_device/commands/logcat.rs b/adb_client/src/server_device/commands/logcat.rs index b2dc0d47..e7c67ae7 100644 --- a/adb_client/src/server_device/commands/logcat.rs +++ b/adb_client/src/server_device/commands/logcat.rs @@ -25,21 +25,21 @@ impl Write for LogFilter { fn write(&mut self, buf: &[u8]) -> io::Result { self.buffer.extend_from_slice(buf); - let buf_clone = self.buffer.clone(); - let mut lines = buf_clone.split_inclusive(|&byte| byte == b'\n').peekable(); - - while let Some(line) = lines.next() { - if lines.peek().is_some() { + let mut lines = self.buffer.split_inclusive(|&byte| byte == b'\n'); + let mut offset = 0; + for line in lines { + let is_line = self.buffer.last().unwrap() == &b'\n'; + if is_line { + offset += line.len(); if self.should_write(line) { self.writer.write_all(line)?; } - } else { - // This is the last (unfinished) element, we keep it for next round - self.buffer = line.to_vec(); - break; } } + self.buffer.as_mut_slice().copy_within(offset.., 0); + self.buffer.truncate(self.buffer[offset..].len()); + Ok(buf.len()) } From f51ba984cad07829a3e4934b4b18de8cc9dd792f Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Sun, 21 Sep 2025 11:04:42 +0200 Subject: [PATCH 02/11] impr: further improve LogFilter by removing split_inclusive --- .../src/server_device/commands/logcat.rs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/adb_client/src/server_device/commands/logcat.rs b/adb_client/src/server_device/commands/logcat.rs index e7c67ae7..35e04ea9 100644 --- a/adb_client/src/server_device/commands/logcat.rs +++ b/adb_client/src/server_device/commands/logcat.rs @@ -23,22 +23,27 @@ impl LogFilter { impl Write for LogFilter { fn write(&mut self, buf: &[u8]) -> io::Result { + // Add newly received bytes to the internal buffer self.buffer.extend_from_slice(buf); - let mut lines = self.buffer.split_inclusive(|&byte| byte == b'\n'); - let mut offset = 0; - for line in lines { - let is_line = self.buffer.last().unwrap() == &b'\n'; - if is_line { - offset += line.len(); - if self.should_write(line) { - self.writer.write_all(line)?; - } + let mut processed = 0; + while let Some(pos) = self.buffer[processed..].iter().position(|&b| b == b'\n') { + // Found a newline, need to process it + let end = processed + pos + 1; // +1 to include the '\n' + let line = &self.buffer[processed..end]; + + if self.should_write(line) { + self.writer.write_all(line)?; } + + processed = end; } - self.buffer.as_mut_slice().copy_within(offset.., 0); - self.buffer.truncate(self.buffer[offset..].len()); + // Keep only remaining bytes after the last complete line + if processed > 0 { + self.buffer.copy_within(processed.., 0); + self.buffer.truncate(self.buffer.len() - processed); + } Ok(buf.len()) } From 060e43590daf93bc8c14c4283a554b446da432cb Mon Sep 17 00:00:00 2001 From: yohane Date: Wed, 6 Aug 2025 19:57:29 +0800 Subject: [PATCH 03/11] Fix:Regex expression parsing transport incorrectly --- adb_client/src/server/models/device_long.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adb_client/src/server/models/device_long.rs b/adb_client/src/server/models/device_long.rs index d22050aa..3174690d 100644 --- a/adb_client/src/server/models/device_long.rs +++ b/adb_client/src/server/models/device_long.rs @@ -93,7 +93,7 @@ impl TryFrom<&[u8]> for DeviceLong { .ok_or(RustADBError::RegexParsingError)? .as_bytes(), )?, - 16, + 10, )?, }) } From 373a5265a031856e527757df779bf0302d01ff04 Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Sun, 21 Sep 2025 11:42:58 +0200 Subject: [PATCH 04/11] chore: v2.1.17 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8f7dcd48..239296a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ homepage = "https://github.com/cocool97/adb_client" keywords = ["adb", "android", "tcp", "usb"] license = "MIT" repository = "https://github.com/cocool97/adb_client" -version = "2.1.16" +version = "2.1.17" rust-version = "1.85.1" # To build locally when working on a new release From e0b6bb01397cf57ac8109a58d789b1daf96270ac Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Sun, 19 Oct 2025 14:58:35 +0200 Subject: [PATCH 05/11] chore: cargo clippy -- -W clippy::pedantic --- adb_cli/Cargo.toml | 10 +++---- adb_cli/src/adb_termios.rs | 4 +-- adb_cli/src/handlers/host_commands.rs | 13 ++++---- adb_cli/src/handlers/local_commands.rs | 2 +- adb_cli/src/main.rs | 8 ++--- adb_cli/src/models/device.rs | 2 +- adb_cli/src/utils.rs | 5 +--- adb_client/Cargo.toml | 30 +++++++++---------- adb_client/src/adb_device_ext.rs | 2 +- adb_client/src/device/adb_message_device.rs | 12 ++++---- .../src/device/adb_message_device_commands.rs | 2 +- adb_client/src/device/adb_tcp_device.rs | 6 ++-- .../src/device/adb_transport_message.rs | 4 +-- adb_client/src/device/adb_usb_device.rs | 29 +++++++++--------- adb_client/src/device/commands/framebuffer.rs | 4 +-- adb_client/src/device/commands/pull.rs | 2 +- adb_client/src/device/commands/push.rs | 2 +- adb_client/src/device/commands/shell.rs | 4 +-- adb_client/src/device/models/adb_rsa_key.rs | 10 ++++--- .../src/device/models/message_commands.rs | 30 +++++++++---------- .../emulator_device/adb_emulator_device.rs | 6 ++-- .../models/adb_emulator_command.rs | 3 +- adb_client/src/error.rs | 3 ++ adb_client/src/mdns/mdns_discovery.rs | 1 - adb_client/src/server/adb_server.rs | 10 +++---- adb_client/src/server/commands/devices.rs | 6 ++-- adb_client/src/server/models/adb_version.rs | 2 +- adb_client/src/server/models/device_long.rs | 16 +++++----- adb_client/src/server/models/server_status.rs | 6 ++-- .../src/server_device/adb_server_device.rs | 6 ++-- .../adb_server_device_commands.rs | 10 +++---- adb_client/src/server_device/commands/list.rs | 2 +- adb_client/src/server_device/commands/recv.rs | 4 +-- adb_client/src/server_device/commands/send.rs | 11 +++---- adb_client/src/server_device/commands/stat.rs | 2 +- .../src/transports/tcp_emulator_transport.rs | 18 +++++------ .../src/transports/tcp_server_transport.rs | 16 +++++----- adb_client/src/transports/tcp_transport.rs | 16 ++++------ adb_client/src/transports/usb_transport.rs | 19 +++++------- pyadb_client/Cargo.toml | 4 +-- pyadb_client/src/adb_server.rs | 9 ++++-- 41 files changed, 175 insertions(+), 176 deletions(-) diff --git a/adb_cli/Cargo.toml b/adb_cli/Cargo.toml index 2885bc91..291062bc 100644 --- a/adb_cli/Cargo.toml +++ b/adb_cli/Cargo.toml @@ -11,11 +11,11 @@ rust-version.workspace = true version.workspace = true [dependencies] -adb_client = { version = "^2.0.0" } -anyhow = { version = "1.0.94" } -clap = { version = "4.5.23", features = ["derive"] } -env_logger = { version = "0.11.5" } -log = { version = "0.4.26" } +adb_client = { version = "^2.1.17" } +anyhow = { version = "1.0.100" } +clap = { version = "4.5.49", features = ["derive"] } +env_logger = { version = "0.11.8" } +log = { version = "0.4.28" } [target.'cfg(unix)'.dependencies] termios = { version = "0.3.3" } diff --git a/adb_cli/src/adb_termios.rs b/adb_cli/src/adb_termios.rs index be45a1eb..2445c37b 100644 --- a/adb_cli/src/adb_termios.rs +++ b/adb_cli/src/adb_termios.rs @@ -13,7 +13,7 @@ pub struct ADBTermios { } impl ADBTermios { - pub fn new(fd: impl AsRawFd) -> Result { + pub fn new(fd: &impl AsRawFd) -> Result { let mut new_termios = Termios::from_fd(fd.as_raw_fd())?; let old_termios = new_termios; // Saves previous state new_termios.c_lflag = 0; @@ -36,7 +36,7 @@ impl Drop for ADBTermios { fn drop(&mut self) { // Custom drop implementation, restores previous termios structure. if let Err(e) = tcsetattr(self.fd, TCSANOW, &self.old_termios) { - log::error!("Error while dropping ADBTermios: {e}") + log::error!("Error while dropping ADBTermios: {e}"); } } } diff --git a/adb_cli/src/handlers/host_commands.rs b/adb_cli/src/handlers/host_commands.rs index 250f4659..5a7c7ee1 100644 --- a/adb_cli/src/handlers/host_commands.rs +++ b/adb_cli/src/handlers/host_commands.rs @@ -53,12 +53,15 @@ pub fn handle_host_commands(server_command: ServerCommand) -> Resul let server_status = adb_server.server_status()?; match server_status.mdns_backend { MDNSBackend::Unknown => log::info!("unknown mdns backend..."), - MDNSBackend::Bonjour => match check { - true => log::info!("mdns daemon version [Bonjour]"), - false => log::info!("ERROR: mdns daemon unavailable"), - }, + MDNSBackend::Bonjour => { + if check { + log::info!("mdns daemon version [Bonjour]"); + } else { + log::info!("ERROR: mdns daemon unavailable"); + } + } MDNSBackend::OpenScreen => { - log::info!("mdns daemon version [Openscreen discovery 0.0.0]") + log::info!("mdns daemon version [Openscreen discovery 0.0.0]"); } } } diff --git a/adb_cli/src/handlers/local_commands.rs b/adb_cli/src/handlers/local_commands.rs index 92411ad3..101310d2 100644 --- a/adb_cli/src/handlers/local_commands.rs +++ b/adb_cli/src/handlers/local_commands.rs @@ -14,7 +14,7 @@ pub fn handle_local_commands( let features = device .host_features()? .iter() - .map(|v| v.to_string()) + .map(ToString::to_string) .reduce(|a, b| format!("{a},{b}")) .ok_or(anyhow!("cannot list features"))?; log::info!("Available host features: {features}"); diff --git a/adb_cli/src/main.rs b/adb_cli/src/main.rs index 3ac5af65..c99e683f 100644 --- a/adb_cli/src/main.rs +++ b/adb_cli/src/main.rs @@ -94,7 +94,7 @@ fn main() -> Result<()> { "Found device {} with addresses {:?}", device.fullname, device.addresses - ) + ); } return Ok(service.shutdown()?); @@ -108,7 +108,7 @@ fn main() -> Result<()> { // Using a scope here would call drop() too early.. #[cfg(any(target_os = "linux", target_os = "macos"))] { - let mut adb_termios = ADBTermios::new(std::io::stdin())?; + let mut adb_termios = ADBTermios::new(&std::io::stdin())?; adb_termios.set_adb_termios()?; device.shell(&mut std::io::stdin(), Box::new(std::io::stdout()))?; } @@ -118,7 +118,7 @@ fn main() -> Result<()> { device.shell(&mut std::io::stdin(), Box::new(std::io::stdout()))?; } } else { - let commands: Vec<&str> = commands.iter().map(|v| v.as_str()).collect(); + let commands: Vec<&str> = commands.iter().map(String::as_str).collect(); device.shell_command(&commands, &mut std::io::stdout())?; } } @@ -136,7 +136,7 @@ fn main() -> Result<()> { } DeviceCommands::Reboot { reboot_type } => { log::info!("Reboots device in mode {reboot_type:?}"); - device.reboot(reboot_type.into())? + device.reboot(reboot_type.into())?; } DeviceCommands::Push { filename, path } => { let mut input = File::open(Path::new(&filename))?; diff --git a/adb_cli/src/models/device.rs b/adb_cli/src/models/device.rs index bcaa9ce1..8e7eefbf 100644 --- a/adb_cli/src/models/device.rs +++ b/adb_cli/src/models/device.rs @@ -19,7 +19,7 @@ pub enum DeviceCommands { /// The package whose activity is to be invoked #[clap(short = 'p', long = "package")] package: String, - /// The activity to be invoked itself, Usually it is MainActivity + /// The activity to be invoked itself, Usually it is `MainActivity` #[clap(short = 'a', long = "activity")] activity: String, }, diff --git a/adb_cli/src/utils.rs b/adb_cli/src/utils.rs index b5b01db3..c471d5ac 100644 --- a/adb_cli/src/utils.rs +++ b/adb_cli/src/utils.rs @@ -5,10 +5,7 @@ pub unsafe fn setup_logger(debug: bool) { // RUST_LOG variable has more priority then "--debug" flag if std::env::var("RUST_LOG").is_err() { - let level = match debug { - true => "trace", - false => "info", - }; + let level = if debug { "trace" } else { "info" }; unsafe { std::env::set_var("RUST_LOG", level) }; } diff --git a/adb_client/Cargo.toml b/adb_client/Cargo.toml index 590f75a5..865152cd 100644 --- a/adb_client/Cargo.toml +++ b/adb_client/Cargo.toml @@ -14,33 +14,33 @@ version.workspace = true base64 = { version = "0.22.1" } bincode = { version = "1.3.3" } byteorder = { version = "1.5.0" } -chrono = { version = "0.4.40", default-features = false, features = ["std"] } -homedir = { version = "= 0.3.4" } -image = { version = "0.25.5", default-features = false } -log = { version = "0.4.26" } -mdns-sd = { version = "0.13.9", default-features = false, features = [ +chrono = { version = "0.4.42", default-features = false, features = ["std"] } +homedir = { version = "=0.3.4" } +image = { version = "0.25.8", default-features = false } +log = { version = "0.4.28" } +mdns-sd = { version = "0.13.11", default-features = false, features = [ "logging", ] } num-bigint = { version = "0.8.4", package = "num-bigint-dig" } num-traits = { version = "0.2.19" } quick-protobuf = { version = "0.8.1" } -rand = { version = "0.9.0" } -rcgen = { version = "0.13.1", default-features = false, features = [ +rand = { version = "0.9.2" } +rcgen = { version = "0.13.2", default-features = false, features = [ "aws_lc_rs", "pem", ] } -regex = { version = "1.11.1", features = ["perf", "std", "unicode"] } -rsa = { version = "0.9.7" } +regex = { version = "1.12.2", features = ["perf", "std", "unicode"] } +rsa = { version = "0.9.8" } rusb = { version = "0.9.4", features = ["vendored"] } -rustls = { version = "0.23.27" } -rustls-pki-types = { version = "1.11.0" } -serde = { version = "1.0.216", features = ["derive"] } -serde_repr = { version = "0.1.19" } +rustls = { version = "0.23.33" } +rustls-pki-types = { version = "1.12.0" } +serde = { version = "1.0.228", features = ["derive"] } +serde_repr = { version = "0.1.20" } sha1 = { version = "0.10.6", features = ["oid"] } -thiserror = { version = "2.0.7" } +thiserror = { version = "2.0.17" } [dev-dependencies] -anyhow = { version = "1.0.93" } +anyhow = { version = "1.0.100" } criterion = { version = "0.6.0" } # Used for benchmarks [[bench]] diff --git a/adb_client/src/adb_device_ext.rs b/adb_client/src/adb_device_ext.rs index 9fc99a4a..a342f3a5 100644 --- a/adb_client/src/adb_device_ext.rs +++ b/adb_client/src/adb_device_ext.rs @@ -13,7 +13,7 @@ pub trait ADBDeviceExt { /// Starts an interactive shell session on the device. /// Input data is read from reader and write to writer. - fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()>; + fn shell(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()>; /// Display the stat information for a remote file fn stat(&mut self, remote_path: &str) -> Result; diff --git a/adb_client/src/device/adb_message_device.rs b/adb_client/src/device/adb_message_device.rs index e3036c94..6964f8cb 100644 --- a/adb_client/src/device/adb_message_device.rs +++ b/adb_client/src/device/adb_message_device.rs @@ -70,7 +70,7 @@ impl ADBMessageDevice { match len.take() { Some(0) | None => { rdr.seek_relative(4)?; - len.replace(rdr.read_u32::()? as u64); + len.replace(u64::from(rdr.read_u32::()?)); } Some(length) => { let remaining_bytes = payload.len() as u64 - rdr.position(); @@ -101,9 +101,9 @@ impl ADBMessageDevice { remote_id: u32, mut reader: R, ) -> std::result::Result<(), RustADBError> { - let mut buffer = [0; BUFFER_SIZE]; + let mut buffer = vec![0; BUFFER_SIZE].into_boxed_slice(); let amount_read = reader.read(&mut buffer)?; - let subcommand_data = MessageSubcommand::Data.with_arg(amount_read as u32); + let subcommand_data = MessageSubcommand::Data.with_arg(u32::try_from(amount_read)?); let mut serialized_message = bincode::serialize(&subcommand_data).map_err(|_e| RustADBError::ConversionError)?; @@ -119,7 +119,7 @@ impl ADBMessageDevice { self.send_and_expect_okay(message)?; loop { - let mut buffer = [0; BUFFER_SIZE]; + let mut buffer = vec![0; BUFFER_SIZE].into_boxed_slice(); match reader.read(&mut buffer) { Ok(0) => { @@ -150,7 +150,7 @@ impl ADBMessageDevice { } } Ok(size) => { - let subcommand_data = MessageSubcommand::Data.with_arg(size as u32); + let subcommand_data = MessageSubcommand::Data.with_arg(u32::try_from(size)?); let mut serialized_message = bincode::serialize(&subcommand_data) .map_err(|_e| RustADBError::ConversionError)?; @@ -178,7 +178,7 @@ impl ADBMessageDevice { } pub(crate) fn stat_with_explicit_ids(&mut self, remote_path: &str) -> Result { - let stat_buffer = MessageSubcommand::Stat.with_arg(remote_path.len() as u32); + let stat_buffer = MessageSubcommand::Stat.with_arg(u32::try_from(remote_path.len())?); let message = ADBTransportMessage::new( MessageCommand::Write, self.get_local_id()?, diff --git a/adb_client/src/device/adb_message_device_commands.rs b/adb_client/src/device/adb_message_device_commands.rs index 78b9e020..994676e3 100644 --- a/adb_client/src/device/adb_message_device_commands.rs +++ b/adb_client/src/device/adb_message_device_commands.rs @@ -11,7 +11,7 @@ impl ADBDeviceExt for ADBMessageDevice { self.shell_command(command, output) } - fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> { + fn shell(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()> { self.shell(reader, writer) } diff --git a/adb_client/src/device/adb_tcp_device.rs b/adb_client/src/device/adb_tcp_device.rs index 5f2e8d3a..96ad8097 100644 --- a/adb_client/src/device/adb_tcp_device.rs +++ b/adb_client/src/device/adb_tcp_device.rs @@ -31,8 +31,8 @@ impl ADBTcpDevice { let message = ADBTransportMessage::new( MessageCommand::Cnxn, - 0x01000000, - 1048576, + 0x0100_0000, + 1_048_576, format!("host::{}\0", env!("CARGO_PKG_NAME")).as_bytes(), ); @@ -75,7 +75,7 @@ impl ADBDeviceExt for ADBTcpDevice { } #[inline] - fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> { + fn shell(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()> { self.inner.shell(reader, writer) } diff --git a/adb_client/src/device/adb_transport_message.rs b/adb_client/src/device/adb_transport_message.rs index d1ef0da0..56a87534 100644 --- a/adb_client/src/device/adb_transport_message.rs +++ b/adb_client/src/device/adb_transport_message.rs @@ -58,12 +58,12 @@ impl ADBTransportMessageHeader { } pub(crate) fn compute_crc32(data: &[u8]) -> u32 { - data.iter().map(|&x| x as u32).sum() + data.iter().map(|&x| u32::from(x)).sum() } fn compute_magic(command: MessageCommand) -> u32 { let command_u32 = command as u32; - command_u32 ^ 0xFFFFFFFF + command_u32 ^ 0xFFFF_FFFF } pub fn as_bytes(&self) -> Result> { diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/device/adb_usb_device.rs index 1de4376e..83ee8127 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/device/adb_usb_device.rs @@ -119,7 +119,7 @@ impl ADBUSBDevice { product_id: u16, private_key_path: PathBuf, ) -> Result { - Self::new_from_transport_inner(USBTransport::new(vendor_id, product_id)?, private_key_path) + Self::new_from_transport_inner(USBTransport::new(vendor_id, product_id)?, &private_key_path) } /// Instantiate a new [`ADBUSBDevice`] from a [`USBTransport`] and an optional private key path. @@ -132,22 +132,21 @@ impl ADBUSBDevice { None => get_default_adb_key_path()?, }; - Self::new_from_transport_inner(transport, private_key_path) + Self::new_from_transport_inner(transport, &private_key_path) } fn new_from_transport_inner( transport: USBTransport, - private_key_path: PathBuf, + private_key_path: &PathBuf, ) -> Result { - let private_key = match read_adb_private_key(&private_key_path)? { - Some(pk) => pk, - None => { - log::warn!( - "No private key found at path {}. Using a temporary random one.", - private_key_path.display() - ); - ADBRsaKey::new_random()? - } + let private_key = if let Some(private_key) = read_adb_private_key(private_key_path)? { + private_key + } else { + log::warn!( + "No private key found at path {}. Using a temporary random one.", + private_key_path.display() + ); + ADBRsaKey::new_random()? }; let mut s = Self { @@ -183,8 +182,8 @@ impl ADBUSBDevice { let message = ADBTransportMessage::new( MessageCommand::Cnxn, - 0x01000000, - 1048576, + 0x0100_0000, + 1_048_576, format!("host::{}\0", env!("CARGO_PKG_NAME")).as_bytes(), ); @@ -260,7 +259,7 @@ impl ADBDeviceExt for ADBUSBDevice { } #[inline] - fn shell<'a>(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> { + fn shell<'a>(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()> { self.inner.shell(reader, writer) } diff --git a/adb_client/src/device/commands/framebuffer.rs b/adb_client/src/device/commands/framebuffer.rs index d41422fe..48b65073 100644 --- a/adb_client/src/device/commands/framebuffer.rs +++ b/adb_client/src/device/commands/framebuffer.rs @@ -32,7 +32,7 @@ impl ADBMessageDevice { payload_cursor.read_to_end(&mut framebuffer_data)?; loop { - if framebuffer_data.len() as u32 == framebuffer_info.size { + if u32::try_from(framebuffer_data.len())? == framebuffer_info.size { break; } @@ -65,7 +65,7 @@ impl ADBMessageDevice { payload_cursor.read_to_end(&mut framebuffer_data)?; loop { - if framebuffer_data.len() as u32 == framebuffer_info.size { + if u32::try_from(framebuffer_data.len())? == framebuffer_info.size { break; } diff --git a/adb_client/src/device/commands/pull.rs b/adb_client/src/device/commands/pull.rs index 9e5bc55e..54898f36 100644 --- a/adb_client/src/device/commands/pull.rs +++ b/adb_client/src/device/commands/pull.rs @@ -29,7 +29,7 @@ impl ADBMessageDevice { std::time::Duration::from_secs(4), )?; - let recv_buffer = MessageSubcommand::Recv.with_arg(source.len() as u32); + let recv_buffer = MessageSubcommand::Recv.with_arg(u32::try_from(source.len())?); let recv_buffer = bincode::serialize(&recv_buffer).map_err(|_e| RustADBError::ConversionError)?; self.send_and_expect_okay(ADBTransportMessage::new( diff --git a/adb_client/src/device/commands/push.rs b/adb_client/src/device/commands/push.rs index d87ee7ae..7b6d450b 100644 --- a/adb_client/src/device/commands/push.rs +++ b/adb_client/src/device/commands/push.rs @@ -14,7 +14,7 @@ impl ADBMessageDevice { let path_header = format!("{},0777", path.as_ref()); - let send_buffer = MessageSubcommand::Send.with_arg(path_header.len() as u32); + let send_buffer = MessageSubcommand::Send.with_arg(u32::try_from(path_header.len())?); let mut send_buffer = bincode::serialize(&send_buffer).map_err(|_e| RustADBError::ConversionError)?; send_buffer.append(&mut path_header.as_bytes().to_vec()); diff --git a/adb_client/src/device/commands/shell.rs b/adb_client/src/device/commands/shell.rs index eea70979..895d9287 100644 --- a/adb_client/src/device/commands/shell.rs +++ b/adb_client/src/device/commands/shell.rs @@ -36,7 +36,7 @@ impl ADBMessageDevice { pub(crate) fn shell( &mut self, mut reader: &mut dyn Read, - mut writer: Box<(dyn Write + Send)>, + mut writer: Box, ) -> Result<()> { self.open_session(b"shell:\0")?; @@ -60,7 +60,7 @@ impl ADBMessageDevice { writer.write_all(&message.into_payload())?; writer.flush()?; } - MessageCommand::Okay => continue, + MessageCommand::Okay => {} _ => return Err(RustADBError::ADBShellNotSupported), } } diff --git a/adb_client/src/device/models/adb_rsa_key.rs b/adb_client/src/device/models/adb_rsa_key.rs index 396f0406..260886a0 100644 --- a/adb_client/src/device/models/adb_rsa_key.rs +++ b/adb_client/src/device/models/adb_rsa_key.rs @@ -6,6 +6,7 @@ use num_traits::cast::ToPrimitive; use rsa::pkcs8::DecodePrivateKey; use rsa::traits::PublicKeyParts; use rsa::{Pkcs1v15Sign, RsaPrivateKey}; +use std::fmt::Write; const ADB_PRIVATE_KEY_SIZE: usize = 2048; const ANDROID_PUBKEY_MODULUS_SIZE_WORDS: u32 = 64; @@ -92,15 +93,16 @@ impl ADBRsaKey { .to_u32() .ok_or(RustADBError::ConversionError)?; - Ok(self.encode_public_key(adb_rsa_pubkey.into_bytes())) + Self::encode_public_key(adb_rsa_pubkey.into_bytes()) } - fn encode_public_key(&self, pub_key: Vec) -> String { + fn encode_public_key(pub_key: Vec) -> Result { let mut encoded = STANDARD.encode(pub_key); encoded.push(' '); - encoded.push_str(&format!("adb_client@{}", env!("CARGO_PKG_VERSION"))); + write!(encoded, "adb_client@{}", env!("CARGO_PKG_VERSION")) + .map_err(|_| RustADBError::ConversionError)?; - encoded + Ok(encoded) } pub fn sign(&self, msg: impl AsRef<[u8]>) -> Result> { diff --git a/adb_client/src/device/models/message_commands.rs b/adb_client/src/device/models/message_commands.rs index ff3918c5..1603b891 100644 --- a/adb_client/src/device/models/message_commands.rs +++ b/adb_client/src/device/models/message_commands.rs @@ -6,32 +6,32 @@ use std::fmt::Display; #[repr(u32)] pub enum MessageCommand { /// Connect to a device - Cnxn = 0x4E584E43, + Cnxn = 0x4E58_4E43, /// Close connection to a device - Clse = 0x45534C43, + Clse = 0x4553_4C43, /// Device ask for authentication - Auth = 0x48545541, + Auth = 0x4854_5541, /// Open a data connection - Open = 0x4E45504F, + Open = 0x4E45_504F, /// Write data to connection - Write = 0x45545257, + Write = 0x4554_5257, /// Server understood the message - Okay = 0x59414B4F, + Okay = 0x5941_4B4F, /// Start a connection using TLS - Stls = 0x534C5453, + Stls = 0x534C_5453, } #[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize_repr, Deserialize_repr)] #[repr(u32)] pub enum MessageSubcommand { - Stat = 0x54415453, - Send = 0x444E4553, - Recv = 0x56434552, - Quit = 0x54495551, - Fail = 0x4C494146, - Done = 0x454E4F44, - Data = 0x41544144, - List = 0x5453494C, + Stat = 0x5441_5453, + Send = 0x444E_4553, + Recv = 0x5643_4552, + Quit = 0x5449_5551, + Fail = 0x4C49_4146, + Done = 0x454E_4F44, + Data = 0x4154_4144, + List = 0x5453_494C, } #[derive(Debug, Serialize, Deserialize)] diff --git a/adb_client/src/emulator_device/adb_emulator_device.rs b/adb_client/src/emulator_device/adb_emulator_device.rs index 9c3ec4fb..60cfaa62 100644 --- a/adb_client/src/emulator_device/adb_emulator_device.rs +++ b/adb_client/src/emulator_device/adb_emulator_device.rs @@ -15,16 +15,16 @@ static EMULATOR_REGEX: LazyLock = LazyLock::new(|| { pub struct ADBEmulatorDevice { /// Unique device identifier. pub identifier: String, - /// Internal [TCPEmulatorTransport] + /// Internal [`TCPEmulatorTransport`] transport: TCPEmulatorTransport, } impl ADBEmulatorDevice { - /// Instantiates a new [ADBEmulatorDevice] + /// Instantiates a new [`ADBEmulatorDevice`] pub fn new(identifier: String, ip_address: Option) -> Result { let ip_address = match ip_address { Some(ip_address) => ip_address, - None => Ipv4Addr::new(127, 0, 0, 1), + None => Ipv4Addr::LOCALHOST, }; let groups = EMULATOR_REGEX diff --git a/adb_client/src/emulator_device/models/adb_emulator_command.rs b/adb_client/src/emulator_device/models/adb_emulator_command.rs index 55f6e912..a20dab0f 100644 --- a/adb_client/src/emulator_device/models/adb_emulator_command.rs +++ b/adb_client/src/emulator_device/models/adb_emulator_command.rs @@ -24,8 +24,7 @@ impl ADBEmulatorCommand { pub(crate) fn skip_response_lines(&self) -> u8 { match self { ADBEmulatorCommand::Authenticate(_) => 1, - ADBEmulatorCommand::Sms(_, _) => 0, - ADBEmulatorCommand::Rotate => 0, + ADBEmulatorCommand::Sms(_, _) | ADBEmulatorCommand::Rotate => 0, } } } diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index 01642116..17997bb2 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -42,6 +42,9 @@ pub enum RustADBError { /// Indicates that an error occurred when converting a value. #[error("Conversion error")] ConversionError, + /// Indicates an error with the integer conversion. + #[error(transparent)] + IntegerConversionError(#[from] std::num::TryFromIntError), /// Remote ADB server does not support shell feature. #[error("Remote ADB server does not support shell feature")] ADBShellNotSupported, diff --git a/adb_client/src/mdns/mdns_discovery.rs b/adb_client/src/mdns/mdns_discovery.rs index 39b4e67f..3a84e88d 100644 --- a/adb_client/src/mdns/mdns_discovery.rs +++ b/adb_client/src/mdns/mdns_discovery.rs @@ -42,7 +42,6 @@ impl MDNSDiscoveryService { | ServiceEvent::ServiceFound(_, _) | ServiceEvent::SearchStopped(_) => { // Ignoring these events. We are only interesting in found devices - continue; } ServiceEvent::ServiceResolved(service_info) => { if let Err(e) = sender.send(MDNSDevice::from(service_info)) { diff --git a/adb_client/src/server/adb_server.rs b/adb_client/src/server/adb_server.rs index 33b79879..783f721c 100644 --- a/adb_client/src/server/adb_server.rs +++ b/adb_client/src/server/adb_server.rs @@ -9,7 +9,7 @@ use std::process::Command; /// Represents an ADB Server #[derive(Debug, Default)] pub struct ADBServer { - /// Internal [TcpStream], lazily initialized + /// Internal [`TcpStream`], lazily initialized pub(crate) transport: Option, /// Address to connect to pub(crate) socket_addr: Option, @@ -21,7 +21,7 @@ pub struct ADBServer { } impl ADBServer { - /// Instantiates a new [ADBServer] + /// Instantiates a new [`ADBServer`] pub fn new(address: SocketAddrV4) -> Self { Self { transport: None, @@ -31,7 +31,7 @@ impl ADBServer { } } - /// Instantiates a new [ADBServer] with a custom adb path + /// Instantiates a new [`ADBServer`] with a custom adb path pub fn new_from_path(address: SocketAddrV4, adb_path: Option) -> Self { Self { transport: None, @@ -46,7 +46,7 @@ impl ADBServer { // ADB Server is local, we start it if not already running let mut command = Command::new(adb_path.as_deref().unwrap_or("adb")); command.arg("start-server"); - for (env_k, env_v) in envs.iter() { + for (env_k, env_v) in envs { command.env(env_k, env_v); } @@ -61,7 +61,7 @@ impl ADBServer { match child { Ok(mut child) => { if let Err(e) = child.wait() { - log::error!("error while starting adb server: {e}") + log::error!("error while starting adb server: {e}"); } } Err(e) => log::error!("error while starting adb server: {e}"), diff --git a/adb_client/src/server/commands/devices.rs b/adb_client/src/server/commands/devices.rs index 9c4dc2c7..d930974a 100644 --- a/adb_client/src/server/commands/devices.rs +++ b/adb_client/src/server/commands/devices.rs @@ -69,12 +69,12 @@ impl ADBServer { .filter(|d| d.identifier.as_str() == name) .collect::>() .len(); - if nb_devices != 1 { + if nb_devices == 1 { + Ok(ADBServerDevice::new(name.to_string(), self.socket_addr)) + } else { Err(RustADBError::DeviceNotFound(format!( "could not find device {name}" ))) - } else { - Ok(ADBServerDevice::new(name.to_string(), self.socket_addr)) } } diff --git a/adb_client/src/server/models/adb_version.rs b/adb_client/src/server/models/adb_version.rs index 07cb4b1e..def13c41 100644 --- a/adb_client/src/server/models/adb_version.rs +++ b/adb_client/src/server/models/adb_version.rs @@ -15,7 +15,7 @@ pub struct AdbVersion { } impl AdbVersion { - /// Instantiates a new [AdbVersion]. + /// Instantiates a new [`AdbVersion`]. pub fn new(minor: u32, revision: u32) -> Self { Self { major: 1, diff --git a/adb_client/src/server/models/device_long.rs b/adb_client/src/server/models/device_long.rs index 3174690d..6b8c92da 100644 --- a/adb_client/src/server/models/device_long.rs +++ b/adb_client/src/server/models/device_long.rs @@ -86,15 +86,13 @@ impl TryFrom<&[u8]> for DeviceLong { None => "Unk".to_string(), Some(device) => String::from_utf8(device.as_bytes().to_vec())?, }, - transport_id: u32::from_str_radix( - str::from_utf8( - groups - .name("transport_id") - .ok_or(RustADBError::RegexParsingError)? - .as_bytes(), - )?, - 10, - )?, + transport_id: (str::from_utf8( + groups + .name("transport_id") + .ok_or(RustADBError::RegexParsingError)? + .as_bytes(), + )?) + .parse::()?, }) } } diff --git a/adb_client/src/server/models/server_status.rs b/adb_client/src/server/models/server_status.rs index a00ff1f9..aeaf0cce 100644 --- a/adb_client/src/server/models/server_status.rs +++ b/adb_client/src/server/models/server_status.rs @@ -48,11 +48,11 @@ impl Display for UsbBackend { #[derive(Debug, Clone, PartialEq, Default)] pub enum MDNSBackend { #[default] - /// Unknown + /// `Unknown` Unknown = 0, - /// Bonjour + /// `Bonjour` Bonjour = 1, - /// OpenScreen + /// `OpenScreen` OpenScreen = 2, } diff --git a/adb_client/src/server_device/adb_server_device.rs b/adb_client/src/server_device/adb_server_device.rs index 1c8d4808..89d0ae2a 100644 --- a/adb_client/src/server_device/adb_server_device.rs +++ b/adb_client/src/server_device/adb_server_device.rs @@ -6,12 +6,12 @@ use std::net::SocketAddrV4; pub struct ADBServerDevice { /// Unique device identifier. pub identifier: Option, - /// Internal [TCPServerTransport] + /// Internal [`TCPServerTransport`] pub(crate) transport: TCPServerTransport, } impl ADBServerDevice { - /// Instantiates a new [ADBServerDevice], knowing its ADB identifier (as returned by `adb devices` command). + /// Instantiates a new [`ADBServerDevice`], knowing its ADB identifier (as returned by `adb devices` command). pub fn new(identifier: String, server_addr: Option) -> Self { let transport = TCPServerTransport::new_or_default(server_addr); @@ -21,7 +21,7 @@ impl ADBServerDevice { } } - /// Instantiates a new [ADBServerDevice], assuming only one is currently connected. + /// Instantiates a new [`ADBServerDevice`], assuming only one is currently connected. pub fn autodetect(server_addr: Option) -> Self { let transport = TCPServerTransport::new_or_default(server_addr); diff --git a/adb_client/src/server_device/adb_server_device_commands.rs b/adb_client/src/server_device/adb_server_device_commands.rs index af276ed0..ca2c938c 100644 --- a/adb_client/src/server_device/adb_server_device_commands.rs +++ b/adb_client/src/server_device/adb_server_device_commands.rs @@ -25,15 +25,14 @@ impl ADBDeviceExt for ADBServerDevice { self.transport .send_adb_request(AdbServerCommand::ShellCommand(command.join(" ")))?; + let mut buffer = vec![0; BUFFER_SIZE].into_boxed_slice(); loop { - let mut buffer = [0; BUFFER_SIZE]; match self.transport.get_raw_connection()?.read(&mut buffer) { Ok(size) => { if size == 0 { return Ok(()); - } else { - output.write_all(&buffer[..size])?; } + output.write_all(&buffer[..size])?; } Err(e) => { return Err(RustADBError::IOError(e)); @@ -49,7 +48,7 @@ impl ADBDeviceExt for ADBServerDevice { fn shell( &mut self, mut reader: &mut dyn Read, - mut writer: Box<(dyn Write + Send)>, + mut writer: Box, ) -> Result<()> { let supported_features = self.host_features()?; if !supported_features.contains(&HostFeatures::ShellV2) @@ -67,8 +66,9 @@ impl ADBDeviceExt for ADBServerDevice { // Reading thread, reads response from adb-server std::thread::spawn(move || -> Result<()> { + let mut buffer = vec![0; BUFFER_SIZE].into_boxed_slice(); + loop { - let mut buffer = [0; BUFFER_SIZE]; match read_stream.read(&mut buffer) { Ok(0) => { read_stream.shutdown(std::net::Shutdown::Both)?; diff --git a/adb_client/src/server_device/commands/list.rs b/adb_client/src/server_device/commands/list.rs index 54ceb024..abdfcc12 100644 --- a/adb_client/src/server_device/commands/list.rs +++ b/adb_client/src/server_device/commands/list.rs @@ -26,7 +26,7 @@ impl ADBServerDevice { // 'DONE' directly without listing anything. fn handle_list_command>(&mut self, path: S) -> Result<()> { let mut len_buf = [0_u8; 4]; - LittleEndian::write_u32(&mut len_buf, path.as_ref().len() as u32); + LittleEndian::write_u32(&mut len_buf, u32::try_from(path.as_ref().len())?); // 4 bytes of command name is already sent by send_sync_request self.transport.get_raw_connection()?.write_all(&len_buf)?; diff --git a/adb_client/src/server_device/commands/recv.rs b/adb_client/src/server_device/commands/recv.rs index d20fceea..ae4b9ddd 100644 --- a/adb_client/src/server_device/commands/recv.rs +++ b/adb_client/src/server_device/commands/recv.rs @@ -5,7 +5,7 @@ use crate::{ use byteorder::{LittleEndian, ReadBytesExt}; use std::io::{BufReader, BufWriter, Read, Write}; -/// Internal structure wrapping a [std::io::Read] and hiding underlying protocol logic. +/// Internal structure wrapping a [`std::io::Read`] and hiding underlying protocol logic. struct ADBRecvCommandReader { inner: R, remaining_data_bytes_to_read: usize, @@ -86,7 +86,7 @@ impl ADBServerDevice { let from_as_bytes = from.as_ref().as_bytes(); let mut buffer = Vec::with_capacity(4 + from_as_bytes.len()); - buffer.extend_from_slice(&(from.as_ref().len() as u32).to_le_bytes()); + buffer.extend_from_slice(&(u32::try_from(from.as_ref().len())?).to_le_bytes()); buffer.extend_from_slice(from_as_bytes); raw_connection.write_all(&buffer)?; diff --git a/adb_client/src/server_device/commands/send.rs b/adb_client/src/server_device/commands/send.rs index 3454c7eb..9cf8b578 100644 --- a/adb_client/src/server_device/commands/send.rs +++ b/adb_client/src/server_device/commands/send.rs @@ -9,7 +9,7 @@ use std::{ time::SystemTime, }; -/// Internal structure wrapping a [std::io::Write] and hiding underlying protocol logic. +/// Internal structure wrapping a [`std::io::Write`] and hiding underlying protocol logic. struct ADBSendCommandWriter { inner: W, } @@ -64,7 +64,7 @@ impl ADBServerDevice { // The name of the command is already sent by get_transport()?.send_sync_request let to_as_bytes = to.as_bytes(); let mut buffer = Vec::with_capacity(4 + to_as_bytes.len()); - buffer.extend_from_slice(&(to.len() as u32).to_le_bytes()); + buffer.extend_from_slice(&(u32::try_from(to.len())?).to_le_bytes()); buffer.extend_from_slice(to_as_bytes); raw_connection.write_all(&buffer)?; @@ -77,9 +77,10 @@ impl ADBServerDevice { // Copy is finished, we can now notify as finished // Have to send DONE + file mtime - let last_modified = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { - Ok(n) => n, - Err(_) => panic!("SystemTime before UNIX EPOCH!"), + let Ok(last_modified) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) else { + return Err(RustADBError::ADBRequestFailed( + "SystemTime before UNIX EPOCH!".into(), + )); }; let mut done_buffer = Vec::with_capacity(8); diff --git a/adb_client/src/server_device/commands/stat.rs b/adb_client/src/server_device/commands/stat.rs index 8e107faf..3d4f4282 100644 --- a/adb_client/src/server_device/commands/stat.rs +++ b/adb_client/src/server_device/commands/stat.rs @@ -10,7 +10,7 @@ use crate::{ impl ADBServerDevice { fn handle_stat_command>(&mut self, path: S) -> Result { let mut len_buf = [0_u8; 4]; - LittleEndian::write_u32(&mut len_buf, path.as_ref().len() as u32); + LittleEndian::write_u32(&mut len_buf, u32::try_from(path.as_ref().len())?); // 4 bytes of command name is already sent by send_sync_request self.transport.get_raw_connection()?.write_all(&len_buf)?; diff --git a/adb_client/src/transports/tcp_emulator_transport.rs b/adb_client/src/transports/tcp_emulator_transport.rs index 9a315422..1b99f5f5 100644 --- a/adb_client/src/transports/tcp_emulator_transport.rs +++ b/adb_client/src/transports/tcp_emulator_transport.rs @@ -17,7 +17,7 @@ pub struct TCPEmulatorTransport { } impl TCPEmulatorTransport { - /// Instantiates a new instance of [TCPEmulatorTransport] + /// Instantiates a new instance of [`TCPEmulatorTransport`] pub fn new(socket_addr: SocketAddrV4) -> Self { Self { socket_addr, @@ -34,11 +34,10 @@ impl TCPEmulatorTransport { ))) } - /// Return authentication token stored in $HOME/.emulator_console_auth_token + /// Return authentication token stored in `$HOME/.emulator_console_auth_token` pub fn get_authentication_token(&mut self) -> Result { - let home = match my_home()? { - Some(home) => home, - None => return Err(RustADBError::NoHomeDirectory), + let Some(home) = my_home()? else { + return Err(RustADBError::NoHomeDirectory); }; let mut f = File::open(home.join(".emulator_console_auth_token"))?; @@ -54,7 +53,7 @@ impl TCPEmulatorTransport { self.send_command(ADBEmulatorCommand::Authenticate(token)) } - /// Send an [ADBEmulatorCommand] to this emulator + /// Send an [`ADBEmulatorCommand`] to this emulator pub(crate) fn send_command(&mut self, command: ADBEmulatorCommand) -> Result<()> { let mut connection = self.get_raw_connection()?; @@ -80,10 +79,11 @@ impl TCPEmulatorTransport { let mut line = String::new(); reader.read_line(&mut line)?; - match line.starts_with("OK") { - true => Ok(()), - false => Err(RustADBError::ADBRequestFailed(line)), + if line.starts_with("OK") { + return Ok(()); } + + Err(RustADBError::ADBRequestFailed(line)) } } diff --git a/adb_client/src/transports/tcp_server_transport.rs b/adb_client/src/transports/tcp_server_transport.rs index 0b0c29b2..20cac72d 100644 --- a/adb_client/src/transports/tcp_server_transport.rs +++ b/adb_client/src/transports/tcp_server_transport.rs @@ -8,7 +8,7 @@ use crate::models::{AdbRequestStatus, SyncCommand}; use crate::{ADBTransport, models::AdbServerCommand}; use crate::{Result, RustADBError}; -const DEFAULT_SERVER_IP: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); +const DEFAULT_SERVER_IP: Ipv4Addr = Ipv4Addr::LOCALHOST; const DEFAULT_SERVER_PORT: u16 = 5037; /// Server transport running on top on TCP @@ -25,7 +25,7 @@ impl Default for TCPServerTransport { } impl TCPServerTransport { - /// Instantiates a new instance of [TCPServerTransport] + /// Instantiates a new instance of [`TCPServerTransport`] pub fn new(socket_addr: SocketAddrV4) -> Self { Self { socket_addr, @@ -33,7 +33,7 @@ impl TCPServerTransport { } } - /// Instantiate a new instance of [TCPServerTransport] using given address, or default if not specified. + /// Instantiate a new instance of [`TCPServerTransport`] using given address, or default if not specified. pub fn new_or_default(socket_addr: Option) -> Self { match socket_addr { Some(s) => Self::new(s), @@ -41,7 +41,7 @@ impl TCPServerTransport { } } - /// Get underlying [SocketAddrV4] + /// Get underlying [`SocketAddrV4`] pub fn get_socketaddr(&self) -> SocketAddrV4 { self.socket_addr } @@ -89,7 +89,7 @@ impl TCPServerTransport { )?) } - /// Send the given [SyncCommand] to ADB server, and checks that the request has been taken in consideration. + /// Send the given [`SyncCommand`] to ADB server, and checks that the request has been taken in consideration. pub(crate) fn send_sync_request(&mut self, command: SyncCommand) -> Result<()> { // First 4 bytes are the name of the command we want to send // (e.g. "SEND", "RECV", "STAT", "LIST") @@ -98,7 +98,7 @@ impl TCPServerTransport { .write_all(command.to_string().as_bytes())?) } - /// Gets the body length from a LittleEndian value + /// Gets the body length from a `LittleEndian` value pub(crate) fn get_body_length(&self) -> Result { let length_buffer = self.read_body_length()?; Ok(LittleEndian::read_u32(&length_buffer)) @@ -112,8 +112,8 @@ impl TCPServerTransport { Ok(length_buffer) } - /// Send the given [AdbCommand] to ADB server, and checks that the request has been taken in consideration. - /// If an error occurred, a [RustADBError] is returned with the response error string. + /// Send the given [`AdbCommand`] to ADB server, and checks that the request has been taken in consideration. + /// If an error occurred, a [`RustADBError`] is returned with the response error string. pub(crate) fn send_adb_request(&mut self, command: AdbServerCommand) -> Result<()> { let adb_command_string = command.to_string(); let adb_request = format!("{:04x}{}", adb_command_string.len(), adb_command_string); diff --git a/adb_client/src/transports/tcp_transport.rs b/adb_client/src/transports/tcp_transport.rs index 95e5484a..d420b28b 100644 --- a/adb_client/src/transports/tcp_transport.rs +++ b/adb_client/src/transports/tcp_transport.rs @@ -16,7 +16,6 @@ use std::{ fs::read_to_string, io::{Read, Write}, net::{Shutdown, SocketAddr, TcpStream}, - ops::{Deref, DerefMut}, path::PathBuf, sync::{Arc, Mutex}, time::Duration, @@ -120,18 +119,15 @@ impl TcpTransport { } pub(crate) fn upgrade_connection(&mut self) -> Result<()> { - let current_connection = match self.current_connection.clone() { - Some(current_connection) => current_connection, - None => { - return Err(RustADBError::UpgradeError( - "cannot upgrade a non-existing connection...".into(), - )); - } + let Some(current_connection) = self.current_connection.clone() else { + return Err(RustADBError::UpgradeError( + "cannot upgrade a non-existing connection...".into(), + )); }; { let mut current_conn_locked = current_connection.lock()?; - match current_conn_locked.deref() { + match &*current_conn_locked { CurrentConnection::Tcp(tcp_stream) => { // TODO: Check if we cannot be more precise @@ -192,7 +188,7 @@ impl ADBTransport for TcpTransport { log::debug!("disconnecting..."); if let Some(current_connection) = &self.current_connection { let mut lock = current_connection.lock()?; - match lock.deref_mut() { + match &mut *lock { CurrentConnection::Tcp(tcp_stream) => { let _ = tcp_stream.shutdown(Shutdown::Both); } diff --git a/adb_client/src/transports/usb_transport.rs b/adb_client/src/transports/usb_transport.rs index 9f536cb7..5310486d 100644 --- a/adb_client/src/transports/usb_transport.rs +++ b/adb_client/src/transports/usb_transport.rs @@ -29,7 +29,7 @@ pub struct USBTransport { impl USBTransport { /// Instantiate a new [`USBTransport`]. - /// Only the first device with given vendor_id and product_id is returned. + /// Only the first device with given `vendor_id` and `product_id` is returned. pub fn new(vendor_id: u16, product_id: u16) -> Result { for device in rusb::devices()?.iter() { if let Ok(descriptor) = device.device_descriptor() { @@ -90,14 +90,13 @@ impl USBTransport { Ok(()) } - fn find_endpoints(&self, handle: &DeviceHandle) -> Result<(Endpoint, Endpoint)> { + fn find_endpoints(handle: &DeviceHandle) -> Result<(Endpoint, Endpoint)> { let mut read_endpoint: Option = None; let mut write_endpoint: Option = None; for n in 0..handle.device().device_descriptor()?.num_configurations() { - let config_desc = match handle.device().config_descriptor(n) { - Ok(c) => c, - Err(_) => continue, + let Ok(config_desc) = handle.device().config_descriptor(n) else { + continue; }; for interface in config_desc.interfaces() { @@ -117,16 +116,14 @@ impl USBTransport { Direction::In => { if let Some(write_endpoint) = write_endpoint { return Ok((endpoint, write_endpoint)); - } else { - read_endpoint = Some(endpoint); } + read_endpoint = Some(endpoint); } Direction::Out => { if let Some(read_endpoint) = read_endpoint { return Ok((read_endpoint, endpoint)); - } else { - write_endpoint = Some(endpoint); } + write_endpoint = Some(endpoint); } } } @@ -150,7 +147,7 @@ impl USBTransport { let write_amount = handle.write_bulk(endpoint.address, &data[offset..end], timeout)?; offset += write_amount; - log::trace!("wrote chunk of size {write_amount} - {offset}/{data_len}",) + log::trace!("wrote chunk of size {write_amount} - {offset}/{data_len}",); } if offset % max_packet_size == 0 { @@ -166,7 +163,7 @@ impl ADBTransport for USBTransport { fn connect(&mut self) -> crate::Result<()> { let device = self.device.open()?; - let (read_endpoint, write_endpoint) = self.find_endpoints(&device)?; + let (read_endpoint, write_endpoint) = Self::find_endpoints(&device)?; Self::configure_endpoint(&device, &read_endpoint)?; log::debug!("got read endpoint: {read_endpoint:?}"); diff --git a/pyadb_client/Cargo.toml b/pyadb_client/Cargo.toml index cecce2a1..4df1adbb 100644 --- a/pyadb_client/Cargo.toml +++ b/pyadb_client/Cargo.toml @@ -21,7 +21,7 @@ name = "stub_gen" [dependencies] adb_client = { path = "../adb_client" } -anyhow = { version = "1.0.95" } -pyo3 = { version = "0.25.0", features = ["abi3-py37", "anyhow"] } +anyhow = { version = "1.0.100" } +pyo3 = { version = "0.25.1", features = ["abi3-py37", "anyhow"] } pyo3-stub-gen = "0.7.0" pyo3-stub-gen-derive = "0.7.0" diff --git a/pyadb_client/src/adb_server.rs b/pyadb_client/src/adb_server.rs index abea3cd0..d3fb7066 100644 --- a/pyadb_client/src/adb_server.rs +++ b/pyadb_client/src/adb_server.rs @@ -16,7 +16,7 @@ pub struct PyADBServer(ADBServer); #[pymethods] impl PyADBServer { #[new] - /// Instantiate a new PyADBServer instance + /// Instantiate a new `PyADBServer` instance pub fn new(address: String) -> PyResult { let address = address.parse::()?; Ok(ADBServer::new(address).into()) @@ -24,7 +24,12 @@ impl PyADBServer { /// List available devices pub fn devices(&mut self) -> Result> { - Ok(self.0.devices()?.into_iter().map(|v| v.into()).collect()) + Ok(self + .0 + .devices()? + .into_iter() + .map(std::convert::Into::into) + .collect()) } /// Get a device, assuming that only one is currently connected From 8f2c3c8d8991a1b06ee6d62f0f0967a6d687a731 Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Wed, 27 Aug 2025 19:40:27 +0200 Subject: [PATCH 06/11] breaking(features): add mdns feature + example --- .github/workflows/python-build.yml | 2 +- .github/workflows/rust-build.yml | 6 +++--- Cargo.toml | 2 +- adb_client/Cargo.toml | 18 +++++++++++++++--- adb_client/README.md | 13 +++++++++++++ adb_client/src/error.rs | 4 ++++ adb_client/src/lib.rs | 9 +++++++++ examples/mdns/Cargo.toml | 15 +++++++++++++++ examples/mdns/src/main.rs | 21 +++++++++++++++++++++ 9 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 examples/mdns/Cargo.toml create mode 100644 examples/mdns/src/main.rs diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index 673556c2..f13e6d44 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -35,4 +35,4 @@ jobs: with: files: | target/wheels/pyadb_client*.whl - target/wheels/pyadb_client*.tar.gz \ No newline at end of file + target/wheels/pyadb_client*.tar.gz diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml index 9b1a1ff8..8fcd1a27 100644 --- a/.github/workflows/rust-build.yml +++ b/.github/workflows/rust-build.yml @@ -18,6 +18,6 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v4 - - name: Build project - run: cargo build --release --all-features \ No newline at end of file + - uses: actions/checkout@v4 + - name: Build project + run: cargo build --release --all-features diff --git a/Cargo.toml b/Cargo.toml index 239296a0..b64aae9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["adb_cli", "adb_client", "pyadb_client"] +members = ["adb_cli", "adb_client", "examples/mdns", "pyadb_client"] resolver = "2" [workspace.package] diff --git a/adb_client/Cargo.toml b/adb_client/Cargo.toml index 865152cd..e8a18fdd 100644 --- a/adb_client/Cargo.toml +++ b/adb_client/Cargo.toml @@ -10,6 +10,14 @@ repository.workspace = true rust-version.workspace = true version.workspace = true +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[features] +default = [] +mdns = ["dep:mdns-sd"] + [dependencies] base64 = { version = "0.22.1" } bincode = { version = "1.3.3" } @@ -18,9 +26,6 @@ chrono = { version = "0.4.42", default-features = false, features = ["std"] } homedir = { version = "=0.3.4" } image = { version = "0.25.8", default-features = false } log = { version = "0.4.28" } -mdns-sd = { version = "0.13.11", default-features = false, features = [ - "logging", -] } num-bigint = { version = "0.8.4", package = "num-bigint-dig" } num-traits = { version = "0.2.19" } quick-protobuf = { version = "0.8.1" } @@ -39,6 +44,13 @@ serde_repr = { version = "0.1.20" } sha1 = { version = "0.10.6", features = ["oid"] } thiserror = { version = "2.0.17" } +######### +# MDNS dependencies +mdns-sd = { version = "0.13.11", default-features = false, features = [ + "logging", +], optional = true } +######### + [dev-dependencies] anyhow = { version = "1.0.100" } criterion = { version = "0.6.0" } # Used for benchmarks diff --git a/adb_client/README.md b/adb_client/README.md index bc8af35b..d284cca7 100644 --- a/adb_client/README.md +++ b/adb_client/README.md @@ -16,6 +16,19 @@ Add `adb_client` crate as a dependency by simply adding it to your `Cargo.toml`: adb_client = "*" ``` +## Crate features + +|Feature|Description|Default?| +|:-----:|:---------:|:-----:| +|`mdns`|Enables mDNS device discovery on local network.|No| + +To deactivate some features you can use the `default-features = false` option in your `Cargo.toml` file and manually specify the features you want to activate: + +```toml +[dependencies] +adb_client = { version = "*", default-features = false, features=[""] } +``` + ## Benchmarks Benchmarks run on `v2.0.6`, on a **Samsung S10 SM-G973F** device and an **Intel i7-1265U** CPU laptop diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index 17997bb2..6b3af989 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -115,9 +115,13 @@ pub enum RustADBError { #[error("upgrade error: {0}")] UpgradeError(String), /// An error occurred while getting mdns devices + #[cfg(feature = "mdns")] + #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] #[error(transparent)] MDNSError(#[from] mdns_sd::Error), /// An error occurred while sending data to channel + #[cfg(feature = "mdns")] + #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] #[error(transparent)] SendError(#[from] std::sync::mpsc::SendError), /// An unknown transport has been provided diff --git a/adb_client/src/lib.rs b/adb_client/src/lib.rs index 8c883876..06dfd4aa 100644 --- a/adb_client/src/lib.rs +++ b/adb_client/src/lib.rs @@ -3,12 +3,19 @@ #![forbid(missing_debug_implementations)] #![forbid(missing_docs)] #![doc = include_str!("../README.md")] +// Feature `doc_cfg` is currently only available on nightly. +// It is activated when cfg `docsrs` is enabled. +// Documentation can be build locally using: +// `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --no-deps --all-features` +#![cfg_attr(docsrs, feature(doc_cfg))] mod adb_device_ext; mod constants; mod device; mod emulator_device; mod error; +#[cfg(feature = "mdns")] +#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] mod mdns; mod models; mod server; @@ -20,6 +27,8 @@ pub use adb_device_ext::ADBDeviceExt; pub use device::{ADBTcpDevice, ADBUSBDevice, is_adb_device, search_adb_devices}; pub use emulator_device::ADBEmulatorDevice; pub use error::{Result, RustADBError}; +#[cfg(feature = "mdns")] +#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] pub use mdns::*; pub use models::{AdbStatResponse, RebootType}; pub use server::*; diff --git a/examples/mdns/Cargo.toml b/examples/mdns/Cargo.toml new file mode 100644 index 00000000..5a673b51 --- /dev/null +++ b/examples/mdns/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "mdns" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true +rust-version.workspace = true + +[dependencies] +adb_client = { path = "../../adb_client", default-features = false, features = [ + "mdns", +] } diff --git a/examples/mdns/src/main.rs b/examples/mdns/src/main.rs new file mode 100644 index 00000000..3f3da82f --- /dev/null +++ b/examples/mdns/src/main.rs @@ -0,0 +1,21 @@ +use adb_client::{MDNSDevice, MDNSDiscoveryService}; +use std::sync::mpsc; +use std::time::Duration; + +fn main() -> Result<(), Box> { + println!("Starting mDNS device discovery..."); + + // Create a channel to receive discovered devices information + let (sender, receiver) = mpsc::channel::(); + + // Create and start the discovery service + let mut discovery = MDNSDiscoveryService::new()?; + discovery.start(sender)?; + + loop { + if let Ok(device) = receiver.recv_timeout(Duration::from_millis(100)) { + println!("Found device: {}", device.fullname); + println!(" Addresses: {:?}", device.addresses); + } + } +} From 38fead7101c0994bde5d21b941efa3862835f27f Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Wed, 27 Aug 2025 19:44:59 +0200 Subject: [PATCH 07/11] doc: add section in README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6fd1369e..02516bb0 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,12 @@ Provides a "real-world" usage example of this library. Improved documentation available [here](./adb_cli/README.md). +## examples + +Some examples are available in the `examples` directory: + +- `examples/mdns`: mDNS device discovery example + ## pyadb_client Python wrapper using `adb_client` library to export classes usable directly from a Python environment. From db853ed67ae6f084d30068170e0cc6a71e4a0d80 Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Wed, 27 Aug 2025 21:00:11 +0200 Subject: [PATCH 08/11] breaking(feature): add usb feature --- adb_client/Cargo.toml | 8 ++++++-- adb_client/README.md | 17 +++++++++-------- adb_client/src/device/adb_transport_message.rs | 4 ---- adb_client/src/device/adb_usb_device.rs | 14 +++++--------- adb_client/src/device/mod.rs | 17 +++++++++++++---- adb_client/src/device/models/mod.rs | 4 ++++ adb_client/src/error.rs | 6 ++++++ adb_client/src/lib.rs | 11 ++++++++++- adb_client/src/transports/mod.rs | 6 ++++++ adb_client/src/transports/tcp_transport.rs | 5 ++--- adb_client/src/utils.rs | 13 ++++++++++++- 11 files changed, 73 insertions(+), 32 deletions(-) diff --git a/adb_client/Cargo.toml b/adb_client/Cargo.toml index e8a18fdd..80c55d57 100644 --- a/adb_client/Cargo.toml +++ b/adb_client/Cargo.toml @@ -17,6 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [] mdns = ["dep:mdns-sd"] +usb = ["dep:rsa", "dep:rusb"] [dependencies] base64 = { version = "0.22.1" } @@ -35,8 +36,6 @@ rcgen = { version = "0.13.2", default-features = false, features = [ "pem", ] } regex = { version = "1.12.2", features = ["perf", "std", "unicode"] } -rsa = { version = "0.9.8" } -rusb = { version = "0.9.4", features = ["vendored"] } rustls = { version = "0.23.33" } rustls-pki-types = { version = "1.12.0" } serde = { version = "1.0.228", features = ["derive"] } @@ -50,6 +49,11 @@ mdns-sd = { version = "0.13.11", default-features = false, features = [ "logging", ], optional = true } ######### +######### +# USB-only dependencies +rsa = { version = "0.9.7", optional = true } +rusb = { version = "0.9.4", features = ["vendored"], optional = true } +######### [dev-dependencies] anyhow = { version = "1.0.100" } diff --git a/adb_client/README.md b/adb_client/README.md index d284cca7..87cd5180 100644 --- a/adb_client/README.md +++ b/adb_client/README.md @@ -18,9 +18,10 @@ adb_client = "*" ## Crate features -|Feature|Description|Default?| -|:-----:|:---------:|:-----:| -|`mdns`|Enables mDNS device discovery on local network.|No| +| Feature | Description | Default? | +| :-----: | :---------------------------------------------: | :------: | +| `mdns` | Enables mDNS device discovery on local network. | No | +| `usb` | Enables interactions with USB devices. | No | To deactivate some features you can use the `default-features = false` option in your `Cargo.toml` file and manually specify the features you want to activate: @@ -37,11 +38,11 @@ Benchmarks run on `v2.0.6`, on a **Samsung S10 SM-G973F** device and an **Intel `ADBServerDevice` performs all operations by using adb server as a bridge. -|File size|Sample size|`ADBServerDevice`|`adb`|Difference| -|:-------:|:---------:|:----------:|:---:|:-----:| -|10 MB|100|350,79 ms|356,30 ms|
-1,57 %
| -|500 MB|50|15,60 s|15,64 s|
-0,25 %
| -|1 GB|20|31,09 s|31,12 s|
-0,10 %
| +| File size | Sample size | `ADBServerDevice` | `adb` | Difference | +| :-------: | :---------: | :---------------: | :-------: | :------------------------------------: | +| 10 MB | 100 | 350,79 ms | 356,30 ms |
-1,57 %
| +| 500 MB | 50 | 15,60 s | 15,64 s |
-0,25 %
| +| 1 GB | 20 | 31,09 s | 31,12 s |
-0,10 %
| ## Examples diff --git a/adb_client/src/device/adb_transport_message.rs b/adb_client/src/device/adb_transport_message.rs index 56a87534..93cd297b 100644 --- a/adb_client/src/device/adb_transport_message.rs +++ b/adb_client/src/device/adb_transport_message.rs @@ -4,10 +4,6 @@ use crate::{Result, RustADBError}; use super::models::MessageCommand; -pub const AUTH_TOKEN: u32 = 1; -pub const AUTH_SIGNATURE: u32 = 2; -pub const AUTH_RSAPUBLICKEY: u32 = 3; - #[derive(Debug)] pub struct ADBTransportMessage { header: ADBTransportMessageHeader, diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/device/adb_usb_device.rs index 83ee8127..c2132021 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/device/adb_usb_device.rs @@ -15,9 +15,13 @@ use super::{ADBRsaKey, ADBTransportMessage}; use crate::ADBDeviceExt; use crate::ADBMessageTransport; use crate::ADBTransport; -use crate::device::adb_transport_message::{AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN}; +use crate::utils::get_default_adb_key_path; use crate::{Result, RustADBError, USBTransport}; +const AUTH_TOKEN: u32 = 1; +const AUTH_SIGNATURE: u32 = 2; +const AUTH_RSAPUBLICKEY: u32 = 3; + pub fn read_adb_private_key>(private_key_path: P) -> Result> { // Try to read the private key file from given path // If the file is not found, return None @@ -92,14 +96,6 @@ pub fn is_adb_device(device: &Device, des: &DeviceDescriptor) false } -pub fn get_default_adb_key_path() -> Result { - homedir::my_home() - .ok() - .flatten() - .map(|home| home.join(".android").join("adbkey")) - .ok_or(RustADBError::NoHomeDirectory) -} - /// Represent a device reached and available over USB. #[derive(Debug)] pub struct ADBUSBDevice { diff --git a/adb_client/src/device/mod.rs b/adb_client/src/device/mod.rs index a34b6a18..d9bbf067 100644 --- a/adb_client/src/device/mod.rs +++ b/adb_client/src/device/mod.rs @@ -2,6 +2,9 @@ mod adb_message_device; mod adb_message_device_commands; mod adb_tcp_device; mod adb_transport_message; + +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] mod adb_usb_device; mod commands; mod message_writer; @@ -11,9 +14,15 @@ mod shell_message_writer; use adb_message_device::ADBMessageDevice; pub use adb_tcp_device::ADBTcpDevice; pub use adb_transport_message::{ADBTransportMessage, ADBTransportMessageHeader}; -pub use adb_usb_device::{ - ADBUSBDevice, get_default_adb_key_path, is_adb_device, search_adb_devices, -}; + +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] +pub use adb_usb_device::{ADBUSBDevice, is_adb_device, search_adb_devices}; + pub use message_writer::MessageWriter; -pub use models::{ADBRsaKey, MessageCommand, MessageSubcommand}; +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] +pub use models::ADBRsaKey; + +pub use models::{MessageCommand, MessageSubcommand}; pub use shell_message_writer::ShellMessageWriter; diff --git a/adb_client/src/device/models/mod.rs b/adb_client/src/device/models/mod.rs index 7f97ceb9..da632e99 100644 --- a/adb_client/src/device/models/mod.rs +++ b/adb_client/src/device/models/mod.rs @@ -1,5 +1,9 @@ +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] mod adb_rsa_key; mod message_commands; +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] pub use adb_rsa_key::ADBRsaKey; pub use message_commands::{MessageCommand, MessageSubcommand}; diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index 6b3af989..19032fae 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -70,6 +70,8 @@ pub enum RustADBError { #[error("Cannot get home directory")] NoHomeDirectory, /// Generic USB error + #[cfg(feature = "usb")] + #[cfg_attr(docsrs, doc(cfg(feature = "usb")))] #[error("USB Error: {0}")] UsbError(#[from] rusb::Error), /// USB device not found @@ -88,6 +90,8 @@ pub enum RustADBError { #[error(transparent)] Base64EncodeError(#[from] base64::EncodeSliceError), /// An error occurred with RSA engine + #[cfg(feature = "usb")] + #[cfg_attr(docsrs, doc(cfg(feature = "usb")))] #[error(transparent)] RSAError(#[from] rsa::errors::Error), /// Cannot convert given data from slice @@ -97,6 +101,8 @@ pub enum RustADBError { #[error("wrong file extension: {0}")] WrongFileExtension(String), /// An error occurred with PKCS8 data + #[cfg(feature = "usb")] + #[cfg_attr(docsrs, doc(cfg(feature = "usb")))] #[error("error with pkcs8: {0}")] RsaPkcs8Error(#[from] rsa::pkcs8::Error), /// Error during certificate generation diff --git a/adb_client/src/lib.rs b/adb_client/src/lib.rs index 06dfd4aa..7b41eee8 100644 --- a/adb_client/src/lib.rs +++ b/adb_client/src/lib.rs @@ -14,9 +14,11 @@ mod constants; mod device; mod emulator_device; mod error; + #[cfg(feature = "mdns")] #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] mod mdns; + mod models; mod server; mod server_device; @@ -24,12 +26,19 @@ mod transports; mod utils; pub use adb_device_ext::ADBDeviceExt; -pub use device::{ADBTcpDevice, ADBUSBDevice, is_adb_device, search_adb_devices}; +pub use device::ADBTcpDevice; + +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] +pub use device::{ADBUSBDevice, is_adb_device, search_adb_devices}; + pub use emulator_device::ADBEmulatorDevice; pub use error::{Result, RustADBError}; + #[cfg(feature = "mdns")] #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] pub use mdns::*; + pub use models::{AdbStatResponse, RebootType}; pub use server::*; pub use server_device::ADBServerDevice; diff --git a/adb_client/src/transports/mod.rs b/adb_client/src/transports/mod.rs index 28e89a06..da50c1fa 100644 --- a/adb_client/src/transports/mod.rs +++ b/adb_client/src/transports/mod.rs @@ -2,10 +2,16 @@ mod tcp_emulator_transport; mod tcp_server_transport; mod tcp_transport; mod traits; + +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] mod usb_transport; pub use tcp_emulator_transport::TCPEmulatorTransport; pub use tcp_server_transport::TCPServerTransport; pub use tcp_transport::TcpTransport; pub use traits::{ADBMessageTransport, ADBTransport}; + +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] pub use usb_transport::USBTransport; diff --git a/adb_client/src/transports/tcp_transport.rs b/adb_client/src/transports/tcp_transport.rs index d420b28b..cb572a58 100644 --- a/adb_client/src/transports/tcp_transport.rs +++ b/adb_client/src/transports/tcp_transport.rs @@ -8,9 +8,8 @@ use rustls::{ use super::{ADBMessageTransport, ADBTransport}; use crate::{ Result, RustADBError, - device::{ - ADBTransportMessage, ADBTransportMessageHeader, MessageCommand, get_default_adb_key_path, - }, + device::{ADBTransportMessage, ADBTransportMessageHeader, MessageCommand}, + utils::get_default_adb_key_path, }; use std::{ fs::read_to_string, diff --git a/adb_client/src/utils.rs b/adb_client/src/utils.rs index d91041d7..4b58deaf 100644 --- a/adb_client/src/utils.rs +++ b/adb_client/src/utils.rs @@ -1,4 +1,7 @@ -use std::{ffi::OsStr, path::Path}; +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, +}; use crate::{Result, RustADBError}; @@ -16,3 +19,11 @@ pub fn check_extension_is_apk>(path: P) -> Result<()> { Ok(()) } + +pub fn get_default_adb_key_path() -> Result { + homedir::my_home() + .ok() + .flatten() + .map(|home| home.join(".android").join("adbkey")) + .ok_or(RustADBError::NoHomeDirectory) +} From ced11d4a81a5ef84364f60d0d88b0399afa4343f Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Mon, 1 Sep 2025 21:40:40 +0200 Subject: [PATCH 09/11] feat: improve modules ordering --- .gitignore | 2 +- adb_cli/src/handlers/emulator_commands.rs | 2 +- adb_cli/src/handlers/host_commands.rs | 5 ++- adb_cli/src/handlers/local_commands.rs | 2 +- adb_cli/src/main.rs | 9 ++-- adb_cli/src/models/host.rs | 2 +- adb_client/README.md | 12 +++--- adb_client/src/adb_device_ext.rs | 2 +- .../{transports/traits => }/adb_transport.rs | 0 adb_client/src/constants.rs | 1 - adb_client/src/device/mod.rs | 28 ------------- adb_client/src/device/models/mod.rs | 9 ---- .../adb_emulator_device.rs | 5 ++- .../commands/mod.rs | 0 .../commands/rotate.rs | 5 ++- .../commands/sms.rs | 5 ++- .../src/{emulator_device => emulator}/mod.rs | 4 +- .../models/adb_emulator_command.rs | 0 .../models/mod.rs | 0 .../tcp_emulator_transport.rs | 5 ++- adb_client/src/error.rs | 6 +-- adb_client/src/lib.rs | 41 ++++++++----------- adb_client/src/mdns/mdns_discovery.rs | 8 ++-- .../adb_message_device.rs | 13 ++++-- .../adb_message_device_commands.rs | 10 +++-- .../adb_message_transport.rs | 6 ++- .../adb_transport_message.rs | 4 +- .../commands/framebuffer.rs | 7 +++- .../commands/install.rs | 7 +++- .../commands/mod.rs | 1 + .../commands/pull.rs | 10 +++-- .../commands/push.rs | 8 ++-- .../commands/reboot.rs | 7 +++- .../commands/shell.rs | 10 +++-- .../commands/stat.rs | 5 ++- .../commands/uninstall.rs | 7 +++- .../commands/utils}/message_writer.rs | 7 ++-- .../src/message_devices/commands/utils/mod.rs | 4 ++ .../commands/utils}/shell_message_writer.rs | 7 ++-- .../message_commands.rs | 0 adb_client/src/message_devices/mod.rs | 14 +++++++ .../tcp}/adb_tcp_device.rs | 10 +++-- adb_client/src/message_devices/tcp/mod.rs | 4 ++ .../tcp}/tcp_transport.rs | 10 +++-- .../usb}/adb_rsa_key.rs | 0 .../usb}/adb_usb_device.rs | 15 ++++--- adb_client/src/message_devices/usb/mod.rs | 6 +++ .../usb}/usb_transport.rs | 8 +++- adb_client/src/models/host_features.rs | 3 ++ adb_client/src/models/mod.rs | 6 +-- adb_client/src/server/adb_server.rs | 2 +- .../{models => server}/adb_server_command.rs | 6 ++- adb_client/src/server/commands/connect.rs | 5 ++- adb_client/src/server/commands/devices.rs | 6 ++- adb_client/src/server/commands/disconnect.rs | 5 ++- adb_client/src/server/commands/kill.rs | 5 ++- adb_client/src/server/commands/mdns.rs | 3 +- adb_client/src/server/commands/pair.rs | 6 ++- adb_client/src/server/commands/reconnect.rs | 5 ++- .../src/server/commands/server_status.rs | 5 ++- adb_client/src/server/commands/version.rs | 5 ++- .../src/server/commands/wait_for_device.rs | 3 +- adb_client/src/server/mod.rs | 4 ++ adb_client/src/server/models/device_long.rs | 3 +- adb_client/src/server/models/device_short.rs | 2 +- .../tcp_server_transport.rs | 3 +- .../src/server_device/adb_server_device.rs | 5 ++- .../adb_server_device_commands.rs | 6 ++- .../src/server_device/commands/forward.rs | 2 +- .../src/server_device/commands/framebuffer.rs | 6 ++- .../server_device/commands/host_features.rs | 3 +- .../src/server_device/commands/install.rs | 2 +- adb_client/src/server_device/commands/list.rs | 3 +- .../src/server_device/commands/logcat.rs | 2 +- .../src/server_device/commands/reboot.rs | 5 +-- .../src/server_device/commands/reconnect.rs | 2 +- adb_client/src/server_device/commands/recv.rs | 9 ++-- .../src/server_device/commands/reverse.rs | 2 +- adb_client/src/server_device/commands/send.rs | 12 ++++-- adb_client/src/server_device/commands/stat.rs | 4 +- .../src/server_device/commands/tcpip.rs | 2 +- .../src/server_device/commands/transport.rs | 2 +- .../src/server_device/commands/uninstall.rs | 2 +- adb_client/src/server_device/commands/usb.rs | 2 +- adb_client/src/transports/mod.rs | 17 -------- adb_client/src/transports/traits/mod.rs | 5 --- examples/mdns/src/main.rs | 3 +- pyadb_client/src/adb_server.rs | 2 +- pyadb_client/src/adb_server_device.rs | 2 +- pyadb_client/src/adb_usb_device.rs | 2 +- pyadb_client/src/models/devices.rs | 2 +- 91 files changed, 290 insertions(+), 224 deletions(-) rename adb_client/src/{transports/traits => }/adb_transport.rs (100%) delete mode 100644 adb_client/src/constants.rs delete mode 100644 adb_client/src/device/mod.rs delete mode 100644 adb_client/src/device/models/mod.rs rename adb_client/src/{emulator_device => emulator}/adb_emulator_device.rs (94%) rename adb_client/src/{emulator_device => emulator}/commands/mod.rs (100%) rename adb_client/src/{emulator_device => emulator}/commands/rotate.rs (72%) rename adb_client/src/{emulator_device => emulator}/commands/sms.rs (80%) rename adb_client/src/{emulator_device => emulator}/mod.rs (61%) rename adb_client/src/{emulator_device => emulator}/models/adb_emulator_command.rs (100%) rename adb_client/src/{emulator_device => emulator}/models/mod.rs (100%) rename adb_client/src/{transports => emulator}/tcp_emulator_transport.rs (97%) rename adb_client/src/{device => message_devices}/adb_message_device.rs (96%) rename adb_client/src/{device => message_devices}/adb_message_device_commands.rs (85%) rename adb_client/src/{transports/traits => message_devices}/adb_message_transport.rs (90%) rename adb_client/src/{device => message_devices}/adb_transport_message.rs (97%) rename adb_client/src/{device => message_devices}/commands/framebuffer.rs (94%) rename adb_client/src/{device => message_devices}/commands/install.rs (87%) rename adb_client/src/{device => message_devices}/commands/mod.rs (89%) rename adb_client/src/{device => message_devices}/commands/pull.rs (85%) rename adb_client/src/{device => message_devices}/commands/push.rs (81%) rename adb_client/src/{device => message_devices}/commands/reboot.rs (66%) rename adb_client/src/{device => message_devices}/commands/shell.rs (90%) rename adb_client/src/{device => message_devices}/commands/stat.rs (69%) rename adb_client/src/{device => message_devices}/commands/uninstall.rs (81%) rename adb_client/src/{device => message_devices/commands/utils}/message_writer.rs (88%) create mode 100644 adb_client/src/message_devices/commands/utils/mod.rs rename adb_client/src/{device => message_devices/commands/utils}/shell_message_writer.rs (85%) rename adb_client/src/{device/models => message_devices}/message_commands.rs (100%) create mode 100644 adb_client/src/message_devices/mod.rs rename adb_client/src/{device => message_devices/tcp}/adb_tcp_device.rs (90%) create mode 100644 adb_client/src/message_devices/tcp/mod.rs rename adb_client/src/{transports => message_devices/tcp}/tcp_transport.rs (97%) rename adb_client/src/{device/models => message_devices/usb}/adb_rsa_key.rs (100%) rename adb_client/src/{device => message_devices/usb}/adb_usb_device.rs (95%) create mode 100644 adb_client/src/message_devices/usb/mod.rs rename adb_client/src/{transports => message_devices/usb}/usb_transport.rs (97%) rename adb_client/src/{models => server}/adb_server_command.rs (97%) rename adb_client/src/{transports => server}/tcp_server_transport.rs (98%) delete mode 100644 adb_client/src/transports/mod.rs delete mode 100644 adb_client/src/transports/traits/mod.rs diff --git a/.gitignore b/.gitignore index a7d61ceb..a3ae0cfc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ target /.vscode venv /.mypy_cache -pyadb_client/pyadb_client.pyi \ No newline at end of file +pyadb_client/pyadb_client.pyi diff --git a/adb_cli/src/handlers/emulator_commands.rs b/adb_cli/src/handlers/emulator_commands.rs index 5855cd7b..dcd6c162 100644 --- a/adb_cli/src/handlers/emulator_commands.rs +++ b/adb_cli/src/handlers/emulator_commands.rs @@ -1,4 +1,4 @@ -use adb_client::ADBEmulatorDevice; +use adb_client::emulator::ADBEmulatorDevice; use crate::models::{EmuCommand, EmulatorCommand}; diff --git a/adb_cli/src/handlers/host_commands.rs b/adb_cli/src/handlers/host_commands.rs index 5a7c7ee1..ba6e61c3 100644 --- a/adb_cli/src/handlers/host_commands.rs +++ b/adb_cli/src/handlers/host_commands.rs @@ -1,4 +1,7 @@ -use adb_client::{ADBServer, DeviceShort, MDNSBackend, Result, WaitForDeviceState}; +use adb_client::{ + Result, + server::{ADBServer, DeviceShort, MDNSBackend, WaitForDeviceState}, +}; use crate::models::{HostCommand, MdnsCommand, ServerCommand}; diff --git a/adb_cli/src/handlers/local_commands.rs b/adb_cli/src/handlers/local_commands.rs index 101310d2..ea67a54c 100644 --- a/adb_cli/src/handlers/local_commands.rs +++ b/adb_cli/src/handlers/local_commands.rs @@ -1,6 +1,6 @@ use std::{fs::File, io::Write}; -use adb_client::ADBServerDevice; +use adb_client::server_device::ADBServerDevice; use anyhow::{Result, anyhow}; use crate::models::LocalDeviceCommand; diff --git a/adb_cli/src/main.rs b/adb_cli/src/main.rs index c99e683f..210ead51 100644 --- a/adb_cli/src/main.rs +++ b/adb_cli/src/main.rs @@ -7,9 +7,12 @@ mod handlers; mod models; mod utils; -use adb_client::{ - ADBDeviceExt, ADBServer, ADBServerDevice, ADBTcpDevice, ADBUSBDevice, MDNSDiscoveryService, -}; +use adb_client::ADBDeviceExt; +use adb_client::mdns::MDNSDiscoveryService; +use adb_client::server::ADBServer; +use adb_client::server_device::ADBServerDevice; +use adb_client::tcp::ADBTcpDevice; +use adb_client::usb::ADBUSBDevice; #[cfg(any(target_os = "linux", target_os = "macos"))] use adb_termios::ADBTermios; diff --git a/adb_cli/src/models/host.rs b/adb_cli/src/models/host.rs index 4161d18e..6904d39d 100644 --- a/adb_cli/src/models/host.rs +++ b/adb_cli/src/models/host.rs @@ -1,6 +1,6 @@ use std::net::SocketAddrV4; -use adb_client::{RustADBError, WaitForDeviceTransport}; +use adb_client::{RustADBError, server::WaitForDeviceTransport}; use clap::Parser; fn parse_wait_for_device_device_transport( diff --git a/adb_client/README.md b/adb_client/README.md index 87cd5180..40e4911f 100644 --- a/adb_client/README.md +++ b/adb_client/README.md @@ -49,7 +49,7 @@ Benchmarks run on `v2.0.6`, on a **Samsung S10 SM-G973F** device and an **Intel ### Get available ADB devices ```rust no_run -use adb_client::ADBServer; +use adb_client::server::ADBServer; use std::net::{SocketAddrV4, Ipv4Addr}; // A custom server address can be provided @@ -65,7 +65,7 @@ server.devices(); #### Launch a command on device ```rust no_run -use adb_client::{ADBServer, ADBDeviceExt}; +use adb_client::{server::ADBServer, ADBDeviceExt}; let mut server = ADBServer::default(); let mut device = server.get_device().expect("cannot get device"); @@ -75,7 +75,7 @@ device.shell_command(&["df", "-h"], &mut std::io::stdout()); #### Push a file to the device ```rust no_run -use adb_client::ADBServer; +use adb_client::server::ADBServer; use std::net::Ipv4Addr; use std::fs::File; use std::path::Path; @@ -91,7 +91,7 @@ device.push(&mut input, "/data/local/tmp"); #### (USB) Launch a command on device ```rust no_run -use adb_client::{ADBUSBDevice, ADBDeviceExt}; +use adb_client::{usb::ADBUSBDevice, ADBDeviceExt}; let vendor_id = 0x04e8; let product_id = 0x6860; @@ -102,7 +102,7 @@ device.shell_command(&["df", "-h"], &mut std::io::stdout()); #### (USB) Push a file to the device ```rust no_run -use adb_client::{ADBUSBDevice, ADBDeviceExt}; +use adb_client::{usb::ADBUSBDevice, ADBDeviceExt}; use std::fs::File; use std::path::Path; @@ -117,7 +117,7 @@ device.push(&mut input, &"/data/local/tmp"); ```rust no_run use std::net::{SocketAddr, IpAddr, Ipv4Addr}; -use adb_client::{ADBTcpDevice, ADBDeviceExt}; +use adb_client::{tcp::ADBTcpDevice, ADBDeviceExt}; let device_ip = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 10)); let device_port = 43210; diff --git a/adb_client/src/adb_device_ext.rs b/adb_client/src/adb_device_ext.rs index a342f3a5..9fd4d1a3 100644 --- a/adb_client/src/adb_device_ext.rs +++ b/adb_client/src/adb_device_ext.rs @@ -6,7 +6,7 @@ use image::{ImageBuffer, ImageFormat, Rgba}; use crate::models::AdbStatResponse; use crate::{RebootType, Result}; -/// Trait representing all features available on both [`crate::ADBServerDevice`] and [`crate::ADBUSBDevice`] +/// Trait representing all features available on both [`crate::server_device::ADBServerDevice`] and [`crate::usb::ADBUSBDevice`] pub trait ADBDeviceExt { /// Runs command in a shell on the device, and write its output and error streams into output. fn shell_command(&mut self, command: &[&str], output: &mut dyn Write) -> Result<()>; diff --git a/adb_client/src/transports/traits/adb_transport.rs b/adb_client/src/adb_transport.rs similarity index 100% rename from adb_client/src/transports/traits/adb_transport.rs rename to adb_client/src/adb_transport.rs diff --git a/adb_client/src/constants.rs b/adb_client/src/constants.rs deleted file mode 100644 index c2eb05ee..00000000 --- a/adb_client/src/constants.rs +++ /dev/null @@ -1 +0,0 @@ -pub const BUFFER_SIZE: usize = 65536; diff --git a/adb_client/src/device/mod.rs b/adb_client/src/device/mod.rs deleted file mode 100644 index d9bbf067..00000000 --- a/adb_client/src/device/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -mod adb_message_device; -mod adb_message_device_commands; -mod adb_tcp_device; -mod adb_transport_message; - -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -mod adb_usb_device; -mod commands; -mod message_writer; -mod models; -mod shell_message_writer; - -use adb_message_device::ADBMessageDevice; -pub use adb_tcp_device::ADBTcpDevice; -pub use adb_transport_message::{ADBTransportMessage, ADBTransportMessageHeader}; - -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -pub use adb_usb_device::{ADBUSBDevice, is_adb_device, search_adb_devices}; - -pub use message_writer::MessageWriter; -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -pub use models::ADBRsaKey; - -pub use models::{MessageCommand, MessageSubcommand}; -pub use shell_message_writer::ShellMessageWriter; diff --git a/adb_client/src/device/models/mod.rs b/adb_client/src/device/models/mod.rs deleted file mode 100644 index da632e99..00000000 --- a/adb_client/src/device/models/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -mod adb_rsa_key; -mod message_commands; - -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -pub use adb_rsa_key::ADBRsaKey; -pub use message_commands::{MessageCommand, MessageSubcommand}; diff --git a/adb_client/src/emulator_device/adb_emulator_device.rs b/adb_client/src/emulator/adb_emulator_device.rs similarity index 94% rename from adb_client/src/emulator_device/adb_emulator_device.rs rename to adb_client/src/emulator/adb_emulator_device.rs index 60cfaa62..d92b5497 100644 --- a/adb_client/src/emulator_device/adb_emulator_device.rs +++ b/adb_client/src/emulator/adb_emulator_device.rs @@ -3,7 +3,10 @@ use std::{ sync::LazyLock, }; -use crate::{ADBServerDevice, ADBTransport, Result, RustADBError, TCPEmulatorTransport}; +use crate::{ + ADBTransport, Result, RustADBError, emulator::tcp_emulator_transport::TCPEmulatorTransport, + server_device::ADBServerDevice, +}; use regex::Regex; static EMULATOR_REGEX: LazyLock = LazyLock::new(|| { diff --git a/adb_client/src/emulator_device/commands/mod.rs b/adb_client/src/emulator/commands/mod.rs similarity index 100% rename from adb_client/src/emulator_device/commands/mod.rs rename to adb_client/src/emulator/commands/mod.rs diff --git a/adb_client/src/emulator_device/commands/rotate.rs b/adb_client/src/emulator/commands/rotate.rs similarity index 72% rename from adb_client/src/emulator_device/commands/rotate.rs rename to adb_client/src/emulator/commands/rotate.rs index 0da9d3ea..d4e9db4f 100644 --- a/adb_client/src/emulator_device/commands/rotate.rs +++ b/adb_client/src/emulator/commands/rotate.rs @@ -1,4 +1,7 @@ -use crate::{ADBEmulatorDevice, Result, emulator_device::ADBEmulatorCommand}; +use crate::{ + Result, + emulator::{ADBEmulatorCommand, ADBEmulatorDevice}, +}; impl ADBEmulatorDevice { /// Send a SMS to this emulator with given content with given phone number diff --git a/adb_client/src/emulator_device/commands/sms.rs b/adb_client/src/emulator/commands/sms.rs similarity index 80% rename from adb_client/src/emulator_device/commands/sms.rs rename to adb_client/src/emulator/commands/sms.rs index 627feb9e..e988db38 100644 --- a/adb_client/src/emulator_device/commands/sms.rs +++ b/adb_client/src/emulator/commands/sms.rs @@ -1,4 +1,7 @@ -use crate::{ADBEmulatorDevice, Result, emulator_device::ADBEmulatorCommand}; +use crate::{ + Result, + emulator::{ADBEmulatorCommand, ADBEmulatorDevice}, +}; impl ADBEmulatorDevice { /// Send a SMS to this emulator with given content with given phone number diff --git a/adb_client/src/emulator_device/mod.rs b/adb_client/src/emulator/mod.rs similarity index 61% rename from adb_client/src/emulator_device/mod.rs rename to adb_client/src/emulator/mod.rs index d3f04502..3f799e88 100644 --- a/adb_client/src/emulator_device/mod.rs +++ b/adb_client/src/emulator/mod.rs @@ -1,5 +1,7 @@ mod adb_emulator_device; mod commands; mod models; +mod tcp_emulator_transport; + pub use adb_emulator_device::ADBEmulatorDevice; -pub(crate) use models::ADBEmulatorCommand; +use models::ADBEmulatorCommand; diff --git a/adb_client/src/emulator_device/models/adb_emulator_command.rs b/adb_client/src/emulator/models/adb_emulator_command.rs similarity index 100% rename from adb_client/src/emulator_device/models/adb_emulator_command.rs rename to adb_client/src/emulator/models/adb_emulator_command.rs diff --git a/adb_client/src/emulator_device/models/mod.rs b/adb_client/src/emulator/models/mod.rs similarity index 100% rename from adb_client/src/emulator_device/models/mod.rs rename to adb_client/src/emulator/models/mod.rs diff --git a/adb_client/src/transports/tcp_emulator_transport.rs b/adb_client/src/emulator/tcp_emulator_transport.rs similarity index 97% rename from adb_client/src/transports/tcp_emulator_transport.rs rename to adb_client/src/emulator/tcp_emulator_transport.rs index 1b99f5f5..7572d040 100644 --- a/adb_client/src/transports/tcp_emulator_transport.rs +++ b/adb_client/src/emulator/tcp_emulator_transport.rs @@ -6,8 +6,9 @@ use std::{ use homedir::my_home; -use super::ADBTransport; -use crate::{Result, RustADBError, emulator_device::ADBEmulatorCommand}; +use crate::{ + Result, RustADBError, adb_transport::ADBTransport, emulator::models::ADBEmulatorCommand, +}; /// Emulator transport running on top on TCP. #[derive(Debug)] diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index 19032fae..c810de43 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -126,10 +126,8 @@ pub enum RustADBError { #[error(transparent)] MDNSError(#[from] mdns_sd::Error), /// An error occurred while sending data to channel - #[cfg(feature = "mdns")] - #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] - #[error(transparent)] - SendError(#[from] std::sync::mpsc::SendError), + #[error("error sending data to channel")] + SendError, /// An unknown transport has been provided #[error("unknown transport: {0}")] UnknownTransport(String), diff --git a/adb_client/src/lib.rs b/adb_client/src/lib.rs index 7b41eee8..63a4cc39 100644 --- a/adb_client/src/lib.rs +++ b/adb_client/src/lib.rs @@ -10,36 +10,27 @@ #![cfg_attr(docsrs, feature(doc_cfg))] mod adb_device_ext; -mod constants; -mod device; -mod emulator_device; +mod adb_transport; +/// Emulator-related definitions +pub mod emulator; mod error; - -#[cfg(feature = "mdns")] -#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] -mod mdns; - +mod message_devices; mod models; -mod server; -mod server_device; -mod transports; -mod utils; -pub use adb_device_ext::ADBDeviceExt; -pub use device::ADBTcpDevice; +/// Server-related definitions +pub mod server; -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -pub use device::{ADBUSBDevice, is_adb_device, search_adb_devices}; - -pub use emulator_device::ADBEmulatorDevice; -pub use error::{Result, RustADBError}; +/// Device reachable by the server related definitions +pub mod server_device; +mod utils; +/// MDNS-related definitions #[cfg(feature = "mdns")] #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] -pub use mdns::*; +pub mod mdns; -pub use models::{AdbStatResponse, RebootType}; -pub use server::*; -pub use server_device::ADBServerDevice; -pub use transports::*; +pub use adb_device_ext::ADBDeviceExt; +use adb_transport::ADBTransport; +pub use error::{Result, RustADBError}; +pub use message_devices::*; +pub use models::{AdbStatResponse, HostFeatures, RebootType}; diff --git a/adb_client/src/mdns/mdns_discovery.rs b/adb_client/src/mdns/mdns_discovery.rs index 3a84e88d..11926c59 100644 --- a/adb_client/src/mdns/mdns_discovery.rs +++ b/adb_client/src/mdns/mdns_discovery.rs @@ -1,7 +1,7 @@ use mdns_sd::{ServiceDaemon, ServiceEvent}; use std::{sync::mpsc::Sender, thread::JoinHandle}; -use crate::{MDNSDevice, Result, RustADBError}; +use crate::{Result, RustADBError, mdns::MDNSDevice}; const ADB_SERVICE_NAME: &str = "_adb-tls-connect._tcp.local."; @@ -44,9 +44,9 @@ impl MDNSDiscoveryService { // Ignoring these events. We are only interesting in found devices } ServiceEvent::ServiceResolved(service_info) => { - if let Err(e) = sender.send(MDNSDevice::from(service_info)) { - return Err(e.into()); - } + return sender + .send(MDNSDevice::from(service_info)) + .map_err(|_| RustADBError::SendError); } } } diff --git a/adb_client/src/device/adb_message_device.rs b/adb_client/src/message_devices/adb_message_device.rs similarity index 96% rename from adb_client/src/device/adb_message_device.rs rename to adb_client/src/message_devices/adb_message_device.rs index 6964f8cb..da0932d3 100644 --- a/adb_client/src/device/adb_message_device.rs +++ b/adb_client/src/message_devices/adb_message_device.rs @@ -2,9 +2,16 @@ use byteorder::{LittleEndian, ReadBytesExt}; use rand::Rng; use std::io::{Cursor, Read, Seek}; -use crate::{ADBMessageTransport, AdbStatResponse, Result, RustADBError, constants::BUFFER_SIZE}; - -use super::{ADBTransportMessage, MessageCommand, models::MessageSubcommand}; +use crate::{ + AdbStatResponse, Result, RustADBError, + message_devices::{ + adb_message_transport::ADBMessageTransport, + adb_transport_message::ADBTransportMessage, + message_commands::{MessageCommand, MessageSubcommand}, + }, +}; + +const BUFFER_SIZE: usize = 65535; /// Generic structure representing an ADB device reachable over an [`ADBMessageTransport`]. /// Structure is totally agnostic over which transport is truly used. diff --git a/adb_client/src/device/adb_message_device_commands.rs b/adb_client/src/message_devices/adb_message_device_commands.rs similarity index 85% rename from adb_client/src/device/adb_message_device_commands.rs rename to adb_client/src/message_devices/adb_message_device_commands.rs index 994676e3..dbb59cc8 100644 --- a/adb_client/src/device/adb_message_device_commands.rs +++ b/adb_client/src/message_devices/adb_message_device_commands.rs @@ -1,11 +1,15 @@ -use crate::{ADBDeviceExt, ADBMessageTransport, RebootType, Result, models::AdbStatResponse}; +use crate::{ + ADBDeviceExt, RebootType, Result, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + }, + models::AdbStatResponse, +}; use std::{ io::{Read, Write}, path::Path, }; -use super::ADBMessageDevice; - impl ADBDeviceExt for ADBMessageDevice { fn shell_command(&mut self, command: &[&str], output: &mut dyn Write) -> Result<()> { self.shell_command(command, output) diff --git a/adb_client/src/transports/traits/adb_message_transport.rs b/adb_client/src/message_devices/adb_message_transport.rs similarity index 90% rename from adb_client/src/transports/traits/adb_message_transport.rs rename to adb_client/src/message_devices/adb_message_transport.rs index 67eefd5e..d56b12ad 100644 --- a/adb_client/src/transports/traits/adb_message_transport.rs +++ b/adb_client/src/message_devices/adb_message_transport.rs @@ -1,7 +1,9 @@ use std::time::Duration; -use super::ADBTransport; -use crate::{Result, device::ADBTransportMessage}; +use crate::{ + Result, adb_transport::ADBTransport, + message_devices::adb_transport_message::ADBTransportMessage, +}; const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(u64::MAX); const DEFAULT_WRITE_TIMEOUT: Duration = Duration::from_secs(2); diff --git a/adb_client/src/device/adb_transport_message.rs b/adb_client/src/message_devices/adb_transport_message.rs similarity index 97% rename from adb_client/src/device/adb_transport_message.rs rename to adb_client/src/message_devices/adb_transport_message.rs index 93cd297b..b5d7f67c 100644 --- a/adb_client/src/device/adb_transport_message.rs +++ b/adb_client/src/message_devices/adb_transport_message.rs @@ -1,8 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::{Result, RustADBError}; - -use super::models::MessageCommand; +use crate::{Result, RustADBError, message_devices::message_commands::MessageCommand}; #[derive(Debug)] pub struct ADBTransportMessage { diff --git a/adb_client/src/device/commands/framebuffer.rs b/adb_client/src/message_devices/commands/framebuffer.rs similarity index 94% rename from adb_client/src/device/commands/framebuffer.rs rename to adb_client/src/message_devices/commands/framebuffer.rs index 48b65073..594a5b11 100644 --- a/adb_client/src/device/commands/framebuffer.rs +++ b/adb_client/src/message_devices/commands/framebuffer.rs @@ -4,8 +4,11 @@ use byteorder::{LittleEndian, ReadBytesExt}; use image::{ImageBuffer, Rgba}; use crate::{ - ADBMessageTransport, Result, RustADBError, - device::{MessageCommand, adb_message_device::ADBMessageDevice}, + Result, RustADBError, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + message_commands::MessageCommand, + }, models::{FrameBufferInfoV1, FrameBufferInfoV2}, }; diff --git a/adb_client/src/device/commands/install.rs b/adb_client/src/message_devices/commands/install.rs similarity index 87% rename from adb_client/src/device/commands/install.rs rename to adb_client/src/message_devices/commands/install.rs index 3e25b625..b3abb4e6 100644 --- a/adb_client/src/device/commands/install.rs +++ b/adb_client/src/message_devices/commands/install.rs @@ -1,8 +1,11 @@ use std::{fs::File, path::Path}; use crate::{ - ADBMessageTransport, Result, - device::{MessageWriter, adb_message_device::ADBMessageDevice}, + Result, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + commands::utils::MessageWriter, + }, utils::check_extension_is_apk, }; diff --git a/adb_client/src/device/commands/mod.rs b/adb_client/src/message_devices/commands/mod.rs similarity index 89% rename from adb_client/src/device/commands/mod.rs rename to adb_client/src/message_devices/commands/mod.rs index d1d3de3c..f1d698ea 100644 --- a/adb_client/src/device/commands/mod.rs +++ b/adb_client/src/message_devices/commands/mod.rs @@ -6,3 +6,4 @@ mod reboot; mod shell; mod stat; mod uninstall; +mod utils; diff --git a/adb_client/src/device/commands/pull.rs b/adb_client/src/message_devices/commands/pull.rs similarity index 85% rename from adb_client/src/device/commands/pull.rs rename to adb_client/src/message_devices/commands/pull.rs index 54898f36..2e75e7c8 100644 --- a/adb_client/src/device/commands/pull.rs +++ b/adb_client/src/message_devices/commands/pull.rs @@ -1,10 +1,12 @@ use std::io::Write; use crate::{ - ADBMessageTransport, Result, RustADBError, - device::{ - ADBTransportMessage, MessageCommand, adb_message_device::ADBMessageDevice, - models::MessageSubcommand, + Result, RustADBError, + message_devices::{ + adb_message_device::ADBMessageDevice, + adb_message_transport::ADBMessageTransport, + adb_transport_message::ADBTransportMessage, + message_commands::{MessageCommand, MessageSubcommand}, }, }; diff --git a/adb_client/src/device/commands/push.rs b/adb_client/src/message_devices/commands/push.rs similarity index 81% rename from adb_client/src/device/commands/push.rs rename to adb_client/src/message_devices/commands/push.rs index 7b6d450b..0be32172 100644 --- a/adb_client/src/device/commands/push.rs +++ b/adb_client/src/message_devices/commands/push.rs @@ -1,10 +1,12 @@ use std::io::Read; use crate::{ - ADBMessageTransport, Result, RustADBError, - device::{ - ADBTransportMessage, MessageCommand, MessageSubcommand, + Result, RustADBError, + message_devices::{ adb_message_device::ADBMessageDevice, + adb_message_transport::ADBMessageTransport, + adb_transport_message::ADBTransportMessage, + message_commands::{MessageCommand, MessageSubcommand}, }, }; diff --git a/adb_client/src/device/commands/reboot.rs b/adb_client/src/message_devices/commands/reboot.rs similarity index 66% rename from adb_client/src/device/commands/reboot.rs rename to adb_client/src/message_devices/commands/reboot.rs index 58438f2f..ce461174 100644 --- a/adb_client/src/device/commands/reboot.rs +++ b/adb_client/src/message_devices/commands/reboot.rs @@ -1,6 +1,9 @@ use crate::{ - ADBMessageTransport, RebootType, Result, - device::{MessageCommand, adb_message_device::ADBMessageDevice}, + RebootType, Result, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + message_commands::MessageCommand, + }, }; impl ADBMessageDevice { diff --git a/adb_client/src/device/commands/shell.rs b/adb_client/src/message_devices/commands/shell.rs similarity index 90% rename from adb_client/src/device/commands/shell.rs rename to adb_client/src/message_devices/commands/shell.rs index 895d9287..7c39a3c1 100644 --- a/adb_client/src/device/commands/shell.rs +++ b/adb_client/src/message_devices/commands/shell.rs @@ -1,10 +1,12 @@ use std::io::{ErrorKind, Read, Write}; -use crate::Result; -use crate::device::ShellMessageWriter; use crate::{ - ADBMessageTransport, RustADBError, - device::{ADBMessageDevice, ADBTransportMessage, MessageCommand}, + Result, RustADBError, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + adb_transport_message::ADBTransportMessage, commands::utils::ShellMessageWriter, + message_commands::MessageCommand, + }, }; impl ADBMessageDevice { diff --git a/adb_client/src/device/commands/stat.rs b/adb_client/src/message_devices/commands/stat.rs similarity index 69% rename from adb_client/src/device/commands/stat.rs rename to adb_client/src/message_devices/commands/stat.rs index 27619b09..7da5896b 100644 --- a/adb_client/src/device/commands/stat.rs +++ b/adb_client/src/message_devices/commands/stat.rs @@ -1,5 +1,8 @@ use crate::{ - ADBMessageTransport, AdbStatResponse, Result, device::adb_message_device::ADBMessageDevice, + AdbStatResponse, Result, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + }, }; impl ADBMessageDevice { diff --git a/adb_client/src/device/commands/uninstall.rs b/adb_client/src/message_devices/commands/uninstall.rs similarity index 81% rename from adb_client/src/device/commands/uninstall.rs rename to adb_client/src/message_devices/commands/uninstall.rs index d2304466..1af47fd8 100644 --- a/adb_client/src/device/commands/uninstall.rs +++ b/adb_client/src/message_devices/commands/uninstall.rs @@ -1,4 +1,9 @@ -use crate::{ADBMessageTransport, Result, device::adb_message_device::ADBMessageDevice}; +use crate::{ + Result, + message_devices::{ + adb_message_device::ADBMessageDevice, adb_message_transport::ADBMessageTransport, + }, +}; impl ADBMessageDevice { pub(crate) fn uninstall(&mut self, package_name: &str) -> Result<()> { diff --git a/adb_client/src/device/message_writer.rs b/adb_client/src/message_devices/commands/utils/message_writer.rs similarity index 88% rename from adb_client/src/device/message_writer.rs rename to adb_client/src/message_devices/commands/utils/message_writer.rs index 8345144d..ae5f53a6 100644 --- a/adb_client/src/device/message_writer.rs +++ b/adb_client/src/message_devices/commands/utils/message_writer.rs @@ -1,8 +1,9 @@ use std::io::{Error, ErrorKind, Result, Write}; -use crate::ADBMessageTransport; - -use super::{ADBTransportMessage, MessageCommand}; +use crate::message_devices::{ + adb_message_transport::ADBMessageTransport, adb_transport_message::ADBTransportMessage, + message_commands::MessageCommand, +}; /// [`Write`] trait implementation to hide underlying ADB protocol write logic. /// diff --git a/adb_client/src/message_devices/commands/utils/mod.rs b/adb_client/src/message_devices/commands/utils/mod.rs new file mode 100644 index 00000000..9a7fd27d --- /dev/null +++ b/adb_client/src/message_devices/commands/utils/mod.rs @@ -0,0 +1,4 @@ +mod message_writer; +mod shell_message_writer; +pub use message_writer::MessageWriter; +pub use shell_message_writer::ShellMessageWriter; diff --git a/adb_client/src/device/shell_message_writer.rs b/adb_client/src/message_devices/commands/utils/shell_message_writer.rs similarity index 85% rename from adb_client/src/device/shell_message_writer.rs rename to adb_client/src/message_devices/commands/utils/shell_message_writer.rs index 5533a1f4..48fe49aa 100644 --- a/adb_client/src/device/shell_message_writer.rs +++ b/adb_client/src/message_devices/commands/utils/shell_message_writer.rs @@ -1,8 +1,9 @@ use std::io::Write; -use crate::ADBMessageTransport; - -use super::{ADBTransportMessage, models::MessageCommand}; +use crate::message_devices::{ + adb_message_transport::ADBMessageTransport, adb_transport_message::ADBTransportMessage, + message_commands::MessageCommand, +}; /// [`Write`] trait implementation to hide underlying ADB protocol write logic for shell commands. pub struct ShellMessageWriter { diff --git a/adb_client/src/device/models/message_commands.rs b/adb_client/src/message_devices/message_commands.rs similarity index 100% rename from adb_client/src/device/models/message_commands.rs rename to adb_client/src/message_devices/message_commands.rs diff --git a/adb_client/src/message_devices/mod.rs b/adb_client/src/message_devices/mod.rs new file mode 100644 index 00000000..f7a105d7 --- /dev/null +++ b/adb_client/src/message_devices/mod.rs @@ -0,0 +1,14 @@ +/// USB-related definitions +#[cfg(feature = "usb")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] +pub mod usb; + +/// Device reachable over TCP related definition +pub mod tcp; + +mod adb_message_device; +mod adb_message_device_commands; +mod adb_message_transport; +mod adb_transport_message; +mod commands; +mod message_commands; diff --git a/adb_client/src/device/adb_tcp_device.rs b/adb_client/src/message_devices/tcp/adb_tcp_device.rs similarity index 90% rename from adb_client/src/device/adb_tcp_device.rs rename to adb_client/src/message_devices/tcp/adb_tcp_device.rs index 96ad8097..55538e62 100644 --- a/adb_client/src/device/adb_tcp_device.rs +++ b/adb_client/src/message_devices/tcp/adb_tcp_device.rs @@ -2,10 +2,12 @@ use std::io::Write; use std::path::Path; use std::{io::Read, net::SocketAddr}; -use super::ADBTransportMessage; -use super::adb_message_device::ADBMessageDevice; -use super::models::MessageCommand; -use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, Result, TcpTransport}; +use crate::message_devices::adb_message_device::ADBMessageDevice; +use crate::message_devices::adb_message_transport::ADBMessageTransport; +use crate::message_devices::adb_transport_message::ADBTransportMessage; +use crate::message_devices::message_commands::MessageCommand; +use crate::tcp::tcp_transport::TcpTransport; +use crate::{ADBDeviceExt, ADBTransport, Result}; /// Represent a device reached and available over USB. #[derive(Debug)] diff --git a/adb_client/src/message_devices/tcp/mod.rs b/adb_client/src/message_devices/tcp/mod.rs new file mode 100644 index 00000000..cd9a81dc --- /dev/null +++ b/adb_client/src/message_devices/tcp/mod.rs @@ -0,0 +1,4 @@ +mod adb_tcp_device; +mod tcp_transport; + +pub use adb_tcp_device::ADBTcpDevice; diff --git a/adb_client/src/transports/tcp_transport.rs b/adb_client/src/message_devices/tcp/tcp_transport.rs similarity index 97% rename from adb_client/src/transports/tcp_transport.rs rename to adb_client/src/message_devices/tcp/tcp_transport.rs index cb572a58..ef628617 100644 --- a/adb_client/src/transports/tcp_transport.rs +++ b/adb_client/src/message_devices/tcp/tcp_transport.rs @@ -5,10 +5,14 @@ use rustls::{ pki_types::{CertificateDer, PrivatePkcs8KeyDer, pem::PemObject}, }; -use super::{ADBMessageTransport, ADBTransport}; use crate::{ Result, RustADBError, - device::{ADBTransportMessage, ADBTransportMessageHeader, MessageCommand}, + adb_transport::ADBTransport, + message_devices::{ + adb_message_transport::ADBMessageTransport, + adb_transport_message::{ADBTransportMessage, ADBTransportMessageHeader}, + message_commands::MessageCommand, + }, utils::get_default_adb_key_path, }; use std::{ @@ -206,7 +210,7 @@ impl ADBMessageTransport for TcpTransport { fn read_message_with_timeout( &mut self, read_timeout: std::time::Duration, - ) -> Result { + ) -> Result { let raw_connection_lock = self.get_current_connection()?; let mut raw_connection = raw_connection_lock.lock()?; diff --git a/adb_client/src/device/models/adb_rsa_key.rs b/adb_client/src/message_devices/usb/adb_rsa_key.rs similarity index 100% rename from adb_client/src/device/models/adb_rsa_key.rs rename to adb_client/src/message_devices/usb/adb_rsa_key.rs diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/message_devices/usb/adb_usb_device.rs similarity index 95% rename from adb_client/src/device/adb_usb_device.rs rename to adb_client/src/message_devices/usb/adb_usb_device.rs index c2132021..5ca2a5d9 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/message_devices/usb/adb_usb_device.rs @@ -9,14 +9,17 @@ use std::path::Path; use std::path::PathBuf; use std::time::Duration; -use super::adb_message_device::ADBMessageDevice; -use super::models::MessageCommand; -use super::{ADBRsaKey, ADBTransportMessage}; use crate::ADBDeviceExt; -use crate::ADBMessageTransport; -use crate::ADBTransport; +use crate::Result; +use crate::RustADBError; +use crate::adb_transport::ADBTransport; +use crate::message_devices::adb_message_device::ADBMessageDevice; +use crate::message_devices::adb_message_transport::ADBMessageTransport; +use crate::message_devices::adb_transport_message::ADBTransportMessage; +use crate::message_devices::message_commands::MessageCommand; +use crate::usb::adb_rsa_key::ADBRsaKey; +use crate::usb::usb_transport::USBTransport; use crate::utils::get_default_adb_key_path; -use crate::{Result, RustADBError, USBTransport}; const AUTH_TOKEN: u32 = 1; const AUTH_SIGNATURE: u32 = 2; diff --git a/adb_client/src/message_devices/usb/mod.rs b/adb_client/src/message_devices/usb/mod.rs new file mode 100644 index 00000000..29d3490c --- /dev/null +++ b/adb_client/src/message_devices/usb/mod.rs @@ -0,0 +1,6 @@ +mod adb_rsa_key; +mod adb_usb_device; +mod usb_transport; + +pub use adb_usb_device::ADBUSBDevice; +pub use usb_transport::USBTransport; diff --git a/adb_client/src/transports/usb_transport.rs b/adb_client/src/message_devices/usb/usb_transport.rs similarity index 97% rename from adb_client/src/transports/usb_transport.rs rename to adb_client/src/message_devices/usb/usb_transport.rs index 5310486d..4d8f7789 100644 --- a/adb_client/src/transports/usb_transport.rs +++ b/adb_client/src/message_devices/usb/usb_transport.rs @@ -5,10 +5,14 @@ use rusb::{ constants::LIBUSB_CLASS_VENDOR_SPEC, }; -use super::{ADBMessageTransport, ADBTransport}; use crate::{ Result, RustADBError, - device::{ADBTransportMessage, ADBTransportMessageHeader, MessageCommand}, + adb_transport::ADBTransport, + message_devices::{ + adb_message_transport::ADBMessageTransport, + adb_transport_message::{ADBTransportMessage, ADBTransportMessageHeader}, + message_commands::MessageCommand, + }, }; #[derive(Clone, Debug)] diff --git a/adb_client/src/models/host_features.rs b/adb_client/src/models/host_features.rs index 85fc22d7..25db03ad 100644 --- a/adb_client/src/models/host_features.rs +++ b/adb_client/src/models/host_features.rs @@ -1,8 +1,11 @@ use std::fmt::Display; +/// Available host features. #[derive(Debug, PartialEq)] pub enum HostFeatures { + /// Shell version 2. ShellV2, + /// Command. Cmd, } diff --git a/adb_client/src/models/mod.rs b/adb_client/src/models/mod.rs index 66f3cefc..5dbc0be3 100644 --- a/adb_client/src/models/mod.rs +++ b/adb_client/src/models/mod.rs @@ -1,15 +1,13 @@ mod adb_request_status; -mod adb_server_command; mod adb_stat_response; mod framebuffer_info; mod host_features; mod reboot_type; mod sync_command; -pub use adb_request_status::AdbRequestStatus; -pub(crate) use adb_server_command::AdbServerCommand; +pub(crate) use adb_request_status::AdbRequestStatus; pub use adb_stat_response::AdbStatResponse; pub(crate) use framebuffer_info::{FrameBufferInfoV1, FrameBufferInfoV2}; pub use host_features::HostFeatures; pub use reboot_type::RebootType; -pub use sync_command::SyncCommand; +pub(crate) use sync_command::SyncCommand; diff --git a/adb_client/src/server/adb_server.rs b/adb_client/src/server/adb_server.rs index 783f721c..ed23d7ff 100644 --- a/adb_client/src/server/adb_server.rs +++ b/adb_client/src/server/adb_server.rs @@ -1,7 +1,7 @@ use crate::ADBTransport; use crate::Result; use crate::RustADBError; -use crate::TCPServerTransport; +use crate::server::tcp_server_transport::TCPServerTransport; use std::collections::HashMap; use std::net::SocketAddrV4; use std::process::Command; diff --git a/adb_client/src/models/adb_server_command.rs b/adb_client/src/server/adb_server_command.rs similarity index 97% rename from adb_client/src/models/adb_server_command.rs rename to adb_client/src/server/adb_server_command.rs index 8790fbc4..337981bb 100644 --- a/adb_client/src/models/adb_server_command.rs +++ b/adb_client/src/server/adb_server_command.rs @@ -1,8 +1,10 @@ use std::fmt::Display; -use crate::{WaitForDeviceState, WaitForDeviceTransport}; +use crate::{ + RebootType, + server::{WaitForDeviceState, WaitForDeviceTransport}, +}; -use super::RebootType; use std::net::SocketAddrV4; pub(crate) enum AdbServerCommand { diff --git a/adb_client/src/server/commands/connect.rs b/adb_client/src/server/commands/connect.rs index 2dab4193..70ca941f 100644 --- a/adb_client/src/server/commands/connect.rs +++ b/adb_client/src/server/commands/connect.rs @@ -1,4 +1,7 @@ -use crate::{ADBServer, Result, RustADBError, models::AdbServerCommand}; +use crate::{ + Result, RustADBError, + server::{ADBServer, AdbServerCommand}, +}; use std::net::SocketAddrV4; impl ADBServer { diff --git a/adb_client/src/server/commands/devices.rs b/adb_client/src/server/commands/devices.rs index d930974a..4e173b37 100644 --- a/adb_client/src/server/commands/devices.rs +++ b/adb_client/src/server/commands/devices.rs @@ -1,8 +1,10 @@ use std::io::Read; use crate::{ - ADBEmulatorDevice, ADBServer, ADBServerDevice, DeviceLong, DeviceShort, Result, RustADBError, - models::AdbServerCommand, + Result, RustADBError, + emulator::ADBEmulatorDevice, + server::{ADBServer, AdbServerCommand, DeviceLong, DeviceShort}, + server_device::ADBServerDevice, }; impl ADBServer { diff --git a/adb_client/src/server/commands/disconnect.rs b/adb_client/src/server/commands/disconnect.rs index 2d4ea1e9..fdf072a6 100644 --- a/adb_client/src/server/commands/disconnect.rs +++ b/adb_client/src/server/commands/disconnect.rs @@ -1,4 +1,7 @@ -use crate::{ADBServer, Result, RustADBError, models::AdbServerCommand}; +use crate::{ + Result, RustADBError, + server::{ADBServer, AdbServerCommand}, +}; use std::net::SocketAddrV4; impl ADBServer { diff --git a/adb_client/src/server/commands/kill.rs b/adb_client/src/server/commands/kill.rs index 89f02f87..669665e5 100644 --- a/adb_client/src/server/commands/kill.rs +++ b/adb_client/src/server/commands/kill.rs @@ -1,4 +1,7 @@ -use crate::{ADBServer, Result, models::AdbServerCommand}; +use crate::{ + Result, + server::{ADBServer, AdbServerCommand}, +}; impl ADBServer { /// Asks the ADB server to quit immediately. diff --git a/adb_client/src/server/commands/mdns.rs b/adb_client/src/server/commands/mdns.rs index 05a8f28d..3be35ca8 100644 --- a/adb_client/src/server/commands/mdns.rs +++ b/adb_client/src/server/commands/mdns.rs @@ -1,7 +1,8 @@ use std::io::BufRead; use crate::{ - ADBServer, MDNSServices, Result, models::AdbServerCommand, server::models::MDNSBackend, + Result, + server::{ADBServer, AdbServerCommand, MDNSServices, models::MDNSBackend}, }; const OPENSCREEN_MDNS_BACKEND: &str = "ADB_MDNS_OPENSCREEN"; diff --git a/adb_client/src/server/commands/pair.rs b/adb_client/src/server/commands/pair.rs index bafbf7da..38d1de18 100644 --- a/adb_client/src/server/commands/pair.rs +++ b/adb_client/src/server/commands/pair.rs @@ -1,5 +1,7 @@ -use crate::models::AdbServerCommand; -use crate::{ADBServer, Result, RustADBError}; +use crate::{ + Result, RustADBError, + server::{ADBServer, AdbServerCommand}, +}; use std::net::SocketAddrV4; impl ADBServer { diff --git a/adb_client/src/server/commands/reconnect.rs b/adb_client/src/server/commands/reconnect.rs index aa24bbd7..042fa18b 100644 --- a/adb_client/src/server/commands/reconnect.rs +++ b/adb_client/src/server/commands/reconnect.rs @@ -1,4 +1,7 @@ -use crate::{ADBServer, Result, models::AdbServerCommand}; +use crate::{ + Result, + server::{ADBServer, AdbServerCommand}, +}; impl ADBServer { /// Reconnect the device diff --git a/adb_client/src/server/commands/server_status.rs b/adb_client/src/server/commands/server_status.rs index dcba402e..d7eb1585 100644 --- a/adb_client/src/server/commands/server_status.rs +++ b/adb_client/src/server/commands/server_status.rs @@ -1,4 +1,7 @@ -use crate::{ADBServer, Result, models::AdbServerCommand, server::models::ServerStatus}; +use crate::{ + Result, + server::{ADBServer, AdbServerCommand, models::ServerStatus}, +}; impl ADBServer { /// Check ADB server status diff --git a/adb_client/src/server/commands/version.rs b/adb_client/src/server/commands/version.rs index 8dd0a526..69ae1713 100644 --- a/adb_client/src/server/commands/version.rs +++ b/adb_client/src/server/commands/version.rs @@ -1,4 +1,7 @@ -use crate::{ADBServer, AdbVersion, Result, models::AdbServerCommand}; +use crate::{ + Result, + server::{ADBServer, AdbServerCommand, AdbVersion}, +}; impl ADBServer { /// Gets server's internal version number. diff --git a/adb_client/src/server/commands/wait_for_device.rs b/adb_client/src/server/commands/wait_for_device.rs index abef15cc..c89b0191 100644 --- a/adb_client/src/server/commands/wait_for_device.rs +++ b/adb_client/src/server/commands/wait_for_device.rs @@ -1,5 +1,6 @@ use crate::{ - ADBServer, Result, WaitForDeviceState, WaitForDeviceTransport, models::AdbServerCommand, + Result, + server::{ADBServer, AdbServerCommand, WaitForDeviceState, WaitForDeviceTransport}, }; impl ADBServer { diff --git a/adb_client/src/server/mod.rs b/adb_client/src/server/mod.rs index d55f1310..30d73410 100644 --- a/adb_client/src/server/mod.rs +++ b/adb_client/src/server/mod.rs @@ -1,6 +1,10 @@ mod adb_server; +mod adb_server_command; mod commands; mod models; +mod tcp_server_transport; pub use adb_server::ADBServer; +pub(crate) use adb_server_command::AdbServerCommand; pub use models::*; +pub use tcp_server_transport::TCPServerTransport; diff --git a/adb_client/src/server/models/device_long.rs b/adb_client/src/server/models/device_long.rs index 6b8c92da..a54ef8fc 100644 --- a/adb_client/src/server/models/device_long.rs +++ b/adb_client/src/server/models/device_long.rs @@ -2,7 +2,8 @@ use std::str::FromStr; use std::sync::LazyLock; use std::{fmt::Display, str}; -use crate::{DeviceState, RustADBError}; +use crate::RustADBError; +use crate::server::DeviceState; use regex::bytes::Regex; static DEVICES_LONG_REGEX: LazyLock = LazyLock::new(|| { diff --git a/adb_client/src/server/models/device_short.rs b/adb_client/src/server/models/device_short.rs index 493cd6ed..1759df00 100644 --- a/adb_client/src/server/models/device_short.rs +++ b/adb_client/src/server/models/device_short.rs @@ -1,7 +1,7 @@ use regex::bytes::Regex; use std::{fmt::Display, str::FromStr, sync::LazyLock}; -use crate::{DeviceState, RustADBError}; +use crate::{RustADBError, server::DeviceState}; static DEVICES_REGEX: LazyLock = LazyLock::new(|| Regex::new("^(\\S+)\t(\\w+)\n?$").expect("Cannot build devices regex")); diff --git a/adb_client/src/transports/tcp_server_transport.rs b/adb_client/src/server/tcp_server_transport.rs similarity index 98% rename from adb_client/src/transports/tcp_server_transport.rs rename to adb_client/src/server/tcp_server_transport.rs index 20cac72d..e78e69a7 100644 --- a/adb_client/src/transports/tcp_server_transport.rs +++ b/adb_client/src/server/tcp_server_transport.rs @@ -4,8 +4,9 @@ use std::str::FromStr; use byteorder::{ByteOrder, LittleEndian}; +use crate::ADBTransport; use crate::models::{AdbRequestStatus, SyncCommand}; -use crate::{ADBTransport, models::AdbServerCommand}; +use crate::server::AdbServerCommand; use crate::{Result, RustADBError}; const DEFAULT_SERVER_IP: Ipv4Addr = Ipv4Addr::LOCALHOST; diff --git a/adb_client/src/server_device/adb_server_device.rs b/adb_client/src/server_device/adb_server_device.rs index 89d0ae2a..136772ab 100644 --- a/adb_client/src/server_device/adb_server_device.rs +++ b/adb_client/src/server_device/adb_server_device.rs @@ -1,4 +1,7 @@ -use crate::{ADBTransport, Result, TCPServerTransport, models::AdbServerCommand}; +use crate::{ + ADBTransport, Result, + server::{AdbServerCommand, TCPServerTransport}, +}; use std::net::SocketAddrV4; /// Represents a device connected to the ADB server. diff --git a/adb_client/src/server_device/adb_server_device_commands.rs b/adb_client/src/server_device/adb_server_device_commands.rs index ca2c938c..62696c97 100644 --- a/adb_client/src/server_device/adb_server_device_commands.rs +++ b/adb_client/src/server_device/adb_server_device_commands.rs @@ -5,12 +5,14 @@ use std::{ use crate::{ ADBDeviceExt, Result, RustADBError, - constants::BUFFER_SIZE, - models::{AdbServerCommand, AdbStatResponse, HostFeatures}, + models::{AdbStatResponse, HostFeatures}, + server::AdbServerCommand, }; use super::ADBServerDevice; +const BUFFER_SIZE: usize = 65535; + impl ADBDeviceExt for ADBServerDevice { fn shell_command(&mut self, command: &[&str], output: &mut dyn Write) -> Result<()> { let supported_features = self.host_features()?; diff --git a/adb_client/src/server_device/commands/forward.rs b/adb_client/src/server_device/commands/forward.rs index ff571f3f..9bf1fb3c 100644 --- a/adb_client/src/server_device/commands/forward.rs +++ b/adb_client/src/server_device/commands/forward.rs @@ -1,4 +1,4 @@ -use crate::{ADBServerDevice, Result, models::AdbServerCommand}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Forward socket connection diff --git a/adb_client/src/server_device/commands/framebuffer.rs b/adb_client/src/server_device/commands/framebuffer.rs index b3a6e9fc..5284226e 100644 --- a/adb_client/src/server_device/commands/framebuffer.rs +++ b/adb_client/src/server_device/commands/framebuffer.rs @@ -4,8 +4,10 @@ use byteorder::{LittleEndian, ReadBytesExt}; use image::{ImageBuffer, Rgba}; use crate::{ - ADBServerDevice, Result, RustADBError, - models::{AdbServerCommand, FrameBufferInfoV1, FrameBufferInfoV2}, + Result, RustADBError, + models::{FrameBufferInfoV1, FrameBufferInfoV2}, + server::AdbServerCommand, + server_device::ADBServerDevice, }; impl ADBServerDevice { diff --git a/adb_client/src/server_device/commands/host_features.rs b/adb_client/src/server_device/commands/host_features.rs index 428b7eb2..d01f74f6 100644 --- a/adb_client/src/server_device/commands/host_features.rs +++ b/adb_client/src/server_device/commands/host_features.rs @@ -1,6 +1,5 @@ use crate::{ - ADBServerDevice, Result, - models::{AdbServerCommand, HostFeatures}, + Result, models::HostFeatures, server::AdbServerCommand, server_device::ADBServerDevice, }; impl ADBServerDevice { diff --git a/adb_client/src/server_device/commands/install.rs b/adb_client/src/server_device/commands/install.rs index 29a77ef5..50e36101 100644 --- a/adb_client/src/server_device/commands/install.rs +++ b/adb_client/src/server_device/commands/install.rs @@ -1,7 +1,7 @@ use std::{fs::File, io::Read, path::Path}; use crate::{ - Result, models::AdbServerCommand, server_device::ADBServerDevice, utils::check_extension_is_apk, + Result, server::AdbServerCommand, server_device::ADBServerDevice, utils::check_extension_is_apk, }; impl ADBServerDevice { diff --git a/adb_client/src/server_device/commands/list.rs b/adb_client/src/server_device/commands/list.rs index abdfcc12..d11e4f6c 100644 --- a/adb_client/src/server_device/commands/list.rs +++ b/adb_client/src/server_device/commands/list.rs @@ -1,6 +1,5 @@ use crate::{ - ADBServerDevice, Result, - models::{AdbServerCommand, SyncCommand}, + Result, models::SyncCommand, server::AdbServerCommand, server_device::ADBServerDevice, }; use byteorder::{ByteOrder, LittleEndian}; use std::{ diff --git a/adb_client/src/server_device/commands/logcat.rs b/adb_client/src/server_device/commands/logcat.rs index 35e04ea9..b427a1af 100644 --- a/adb_client/src/server_device/commands/logcat.rs +++ b/adb_client/src/server_device/commands/logcat.rs @@ -1,6 +1,6 @@ use std::io::{self, Write}; -use crate::{ADBDeviceExt, ADBServerDevice, Result}; +use crate::{ADBDeviceExt, Result, server_device::ADBServerDevice}; struct LogFilter { writer: W, diff --git a/adb_client/src/server_device/commands/reboot.rs b/adb_client/src/server_device/commands/reboot.rs index 3829e837..a41b0b8f 100644 --- a/adb_client/src/server_device/commands/reboot.rs +++ b/adb_client/src/server_device/commands/reboot.rs @@ -1,7 +1,4 @@ -use crate::{ - ADBServerDevice, Result, - models::{AdbServerCommand, RebootType}, -}; +use crate::{Result, models::RebootType, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Reboots the device diff --git a/adb_client/src/server_device/commands/reconnect.rs b/adb_client/src/server_device/commands/reconnect.rs index 03e889ae..0c4abf78 100644 --- a/adb_client/src/server_device/commands/reconnect.rs +++ b/adb_client/src/server_device/commands/reconnect.rs @@ -1,4 +1,4 @@ -use crate::{ADBServerDevice, Result, models::AdbServerCommand}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Reconnect device diff --git a/adb_client/src/server_device/commands/recv.rs b/adb_client/src/server_device/commands/recv.rs index ae4b9ddd..e31764eb 100644 --- a/adb_client/src/server_device/commands/recv.rs +++ b/adb_client/src/server_device/commands/recv.rs @@ -1,6 +1,5 @@ use crate::{ - ADBServerDevice, Result, constants, - models::{AdbServerCommand, SyncCommand}, + Result, models::SyncCommand, server::AdbServerCommand, server_device::ADBServerDevice, }; use byteorder::{LittleEndian, ReadBytesExt}; use std::io::{BufReader, BufWriter, Read, Write}; @@ -63,6 +62,8 @@ impl Read for ADBRecvCommandReader { } } +const BUFFER_SIZE: usize = 65535; + impl ADBServerDevice { /// Receives path to stream from the device. pub fn pull(&mut self, path: &dyn AsRef, stream: &mut dyn Write) -> Result<()> { @@ -92,8 +93,8 @@ impl ADBServerDevice { let reader = ADBRecvCommandReader::new(raw_connection); std::io::copy( - &mut BufReader::with_capacity(constants::BUFFER_SIZE, reader), - &mut BufWriter::with_capacity(constants::BUFFER_SIZE, output), + &mut BufReader::with_capacity(BUFFER_SIZE, reader), + &mut BufWriter::with_capacity(BUFFER_SIZE, output), )?; // Connection should've been left in SYNC mode by now diff --git a/adb_client/src/server_device/commands/reverse.rs b/adb_client/src/server_device/commands/reverse.rs index b7d06db7..85419180 100644 --- a/adb_client/src/server_device/commands/reverse.rs +++ b/adb_client/src/server_device/commands/reverse.rs @@ -1,4 +1,4 @@ -use crate::{ADBServerDevice, Result, models::AdbServerCommand}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Reverse socket connection diff --git a/adb_client/src/server_device/commands/send.rs b/adb_client/src/server_device/commands/send.rs index 9cf8b578..f384e0b0 100644 --- a/adb_client/src/server_device/commands/send.rs +++ b/adb_client/src/server_device/commands/send.rs @@ -1,6 +1,8 @@ use crate::{ - ADBServerDevice, Result, RustADBError, constants, - models::{AdbRequestStatus, AdbServerCommand, SyncCommand}, + Result, RustADBError, + models::{AdbRequestStatus, SyncCommand}, + server::AdbServerCommand, + server_device::ADBServerDevice, }; use std::{ convert::TryInto, @@ -40,6 +42,8 @@ impl Write for ADBSendCommandWriter { } } +const BUFFER_SIZE: usize = 65535; + impl ADBServerDevice { /// Send stream to path on the device. pub fn push>(&mut self, stream: R, path: A) -> Result<()> { @@ -71,8 +75,8 @@ impl ADBServerDevice { let writer = ADBSendCommandWriter::new(raw_connection); std::io::copy( - &mut BufReader::with_capacity(constants::BUFFER_SIZE, input), - &mut BufWriter::with_capacity(constants::BUFFER_SIZE, writer), + &mut BufReader::with_capacity(BUFFER_SIZE, input), + &mut BufWriter::with_capacity(BUFFER_SIZE, writer), )?; // Copy is finished, we can now notify as finished diff --git a/adb_client/src/server_device/commands/stat.rs b/adb_client/src/server_device/commands/stat.rs index 3d4f4282..a0ea30d6 100644 --- a/adb_client/src/server_device/commands/stat.rs +++ b/adb_client/src/server_device/commands/stat.rs @@ -3,8 +3,8 @@ use std::io::{Read, Write}; use byteorder::{ByteOrder, LittleEndian}; use crate::{ - ADBServerDevice, Result, RustADBError, - models::{AdbServerCommand, AdbStatResponse, SyncCommand}, + AdbStatResponse, Result, RustADBError, models::SyncCommand, server::AdbServerCommand, + server_device::ADBServerDevice, }; impl ADBServerDevice { diff --git a/adb_client/src/server_device/commands/tcpip.rs b/adb_client/src/server_device/commands/tcpip.rs index 3cb01ed2..5f4d6c98 100644 --- a/adb_client/src/server_device/commands/tcpip.rs +++ b/adb_client/src/server_device/commands/tcpip.rs @@ -1,4 +1,4 @@ -use crate::{ADBServerDevice, Result, models::AdbServerCommand}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Set adb daemon to tcp/ip mode diff --git a/adb_client/src/server_device/commands/transport.rs b/adb_client/src/server_device/commands/transport.rs index 25b6ccb4..29f429c8 100644 --- a/adb_client/src/server_device/commands/transport.rs +++ b/adb_client/src/server_device/commands/transport.rs @@ -1,4 +1,4 @@ -use crate::{ADBServerDevice, Result, models::AdbServerCommand}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Asks ADB server to switch the connection to either the device or emulator connect to/running on the host. Will fail if there is more than one such device/emulator available. diff --git a/adb_client/src/server_device/commands/uninstall.rs b/adb_client/src/server_device/commands/uninstall.rs index 32b8f954..2f8e9efa 100644 --- a/adb_client/src/server_device/commands/uninstall.rs +++ b/adb_client/src/server_device/commands/uninstall.rs @@ -1,6 +1,6 @@ use std::io::Read; -use crate::{Result, models::AdbServerCommand, server_device::ADBServerDevice}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Uninstall a package from device diff --git a/adb_client/src/server_device/commands/usb.rs b/adb_client/src/server_device/commands/usb.rs index e3c0ce20..df711a30 100644 --- a/adb_client/src/server_device/commands/usb.rs +++ b/adb_client/src/server_device/commands/usb.rs @@ -1,4 +1,4 @@ -use crate::{ADBServerDevice, Result, models::AdbServerCommand}; +use crate::{Result, server::AdbServerCommand, server_device::ADBServerDevice}; impl ADBServerDevice { /// Set adb daemon to usb mode diff --git a/adb_client/src/transports/mod.rs b/adb_client/src/transports/mod.rs deleted file mode 100644 index da50c1fa..00000000 --- a/adb_client/src/transports/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod tcp_emulator_transport; -mod tcp_server_transport; -mod tcp_transport; -mod traits; - -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -mod usb_transport; - -pub use tcp_emulator_transport::TCPEmulatorTransport; -pub use tcp_server_transport::TCPServerTransport; -pub use tcp_transport::TcpTransport; -pub use traits::{ADBMessageTransport, ADBTransport}; - -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] -pub use usb_transport::USBTransport; diff --git a/adb_client/src/transports/traits/mod.rs b/adb_client/src/transports/traits/mod.rs deleted file mode 100644 index e655c814..00000000 --- a/adb_client/src/transports/traits/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod adb_message_transport; -mod adb_transport; - -pub use adb_message_transport::ADBMessageTransport; -pub use adb_transport::ADBTransport; diff --git a/examples/mdns/src/main.rs b/examples/mdns/src/main.rs index 3f3da82f..16861c17 100644 --- a/examples/mdns/src/main.rs +++ b/examples/mdns/src/main.rs @@ -1,7 +1,8 @@ -use adb_client::{MDNSDevice, MDNSDiscoveryService}; use std::sync::mpsc; use std::time::Duration; +use adb_client::mdns::{MDNSDevice, MDNSDiscoveryService}; + fn main() -> Result<(), Box> { println!("Starting mDNS device discovery..."); diff --git a/pyadb_client/src/adb_server.rs b/pyadb_client/src/adb_server.rs index d3fb7066..73982955 100644 --- a/pyadb_client/src/adb_server.rs +++ b/pyadb_client/src/adb_server.rs @@ -1,6 +1,6 @@ use std::net::SocketAddrV4; -use adb_client::ADBServer; +use adb_client::server::ADBServer; use anyhow::Result; use pyo3::{PyResult, pyclass, pymethods}; use pyo3_stub_gen_derive::{gen_stub_pyclass, gen_stub_pymethods}; diff --git a/pyadb_client/src/adb_server_device.rs b/pyadb_client/src/adb_server_device.rs index e6fd207e..27f979b7 100644 --- a/pyadb_client/src/adb_server_device.rs +++ b/pyadb_client/src/adb_server_device.rs @@ -1,4 +1,4 @@ -use adb_client::{ADBDeviceExt, ADBServerDevice}; +use adb_client::{ADBDeviceExt, server_device::ADBServerDevice}; use anyhow::Result; use pyo3::{pyclass, pymethods}; use pyo3_stub_gen_derive::{gen_stub_pyclass, gen_stub_pymethods}; diff --git a/pyadb_client/src/adb_usb_device.rs b/pyadb_client/src/adb_usb_device.rs index ea3cf5e6..44d2433c 100644 --- a/pyadb_client/src/adb_usb_device.rs +++ b/pyadb_client/src/adb_usb_device.rs @@ -1,6 +1,6 @@ use std::{fs::File, path::PathBuf}; -use adb_client::{ADBDeviceExt, ADBUSBDevice}; +use adb_client::{ADBDeviceExt, usb::ADBUSBDevice}; use anyhow::Result; use pyo3::{pyclass, pymethods}; use pyo3_stub_gen_derive::{gen_stub_pyclass, gen_stub_pymethods}; diff --git a/pyadb_client/src/models/devices.rs b/pyadb_client/src/models/devices.rs index 3ace3ef5..3ede6771 100644 --- a/pyadb_client/src/models/devices.rs +++ b/pyadb_client/src/models/devices.rs @@ -1,4 +1,4 @@ -use adb_client::DeviceShort; +use adb_client::server::DeviceShort; use pyo3::{pyclass, pymethods}; use pyo3_stub_gen_derive::{gen_stub_pyclass, gen_stub_pymethods}; From 2eed32649ca2306c6484aefac704af646868c38d Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Wed, 3 Sep 2025 20:53:57 +0200 Subject: [PATCH 10/11] feat: improve README.md --- adb_client/README.md | 89 ++------------------ adb_client/src/message_devices/tcp/README.md | 13 +++ adb_client/src/message_devices/tcp/mod.rs | 2 + adb_client/src/message_devices/usb/README.md | 26 ++++++ adb_client/src/message_devices/usb/mod.rs | 2 + adb_client/src/server/README.md | 15 ++++ adb_client/src/server/mod.rs | 2 + adb_client/src/server_device/README.md | 25 ++++++ adb_client/src/server_device/mod.rs | 2 + 9 files changed, 94 insertions(+), 82 deletions(-) create mode 100644 adb_client/src/message_devices/tcp/README.md create mode 100644 adb_client/src/message_devices/usb/README.md create mode 100644 adb_client/src/server/README.md create mode 100644 adb_client/src/server_device/README.md diff --git a/adb_client/README.md b/adb_client/README.md index 40e4911f..cc01cc97 100644 --- a/adb_client/README.md +++ b/adb_client/README.md @@ -27,9 +27,15 @@ To deactivate some features you can use the `default-features = false` option in ```toml [dependencies] -adb_client = { version = "*", default-features = false, features=[""] } +adb_client = { version = "*" } ``` +## Examples + +Usage examples can be found in the `examples/` directory of this repository. + +Some example are also provided in the various `README.md` files of modules. + ## Benchmarks Benchmarks run on `v2.0.6`, on a **Samsung S10 SM-G973F** device and an **Intel i7-1265U** CPU laptop @@ -43,84 +49,3 @@ Benchmarks run on `v2.0.6`, on a **Samsung S10 SM-G973F** device and an **Intel | 10 MB | 100 | 350,79 ms | 356,30 ms |
-1,57 %
| | 500 MB | 50 | 15,60 s | 15,64 s |
-0,25 %
| | 1 GB | 20 | 31,09 s | 31,12 s |
-0,10 %
| - -## Examples - -### Get available ADB devices - -```rust no_run -use adb_client::server::ADBServer; -use std::net::{SocketAddrV4, Ipv4Addr}; - -// A custom server address can be provided -let server_ip = Ipv4Addr::new(127, 0, 0, 1); -let server_port = 5037; - -let mut server = ADBServer::new(SocketAddrV4::new(server_ip, server_port)); -server.devices(); -``` - -### Using ADB server as bridge - -#### Launch a command on device - -```rust no_run -use adb_client::{server::ADBServer, ADBDeviceExt}; - -let mut server = ADBServer::default(); -let mut device = server.get_device().expect("cannot get device"); -device.shell_command(&["df", "-h"], &mut std::io::stdout()); -``` - -#### Push a file to the device - -```rust no_run -use adb_client::server::ADBServer; -use std::net::Ipv4Addr; -use std::fs::File; -use std::path::Path; - -let mut server = ADBServer::default(); -let mut device = server.get_device().expect("cannot get device"); -let mut input = File::open(Path::new("/tmp/f")).expect("Cannot open file"); -device.push(&mut input, "/data/local/tmp"); -``` - -### Interact directly with end devices - -#### (USB) Launch a command on device - -```rust no_run -use adb_client::{usb::ADBUSBDevice, ADBDeviceExt}; - -let vendor_id = 0x04e8; -let product_id = 0x6860; -let mut device = ADBUSBDevice::new(vendor_id, product_id).expect("cannot find device"); -device.shell_command(&["df", "-h"], &mut std::io::stdout()); -``` - -#### (USB) Push a file to the device - -```rust no_run -use adb_client::{usb::ADBUSBDevice, ADBDeviceExt}; -use std::fs::File; -use std::path::Path; - -let vendor_id = 0x04e8; -let product_id = 0x6860; -let mut device = ADBUSBDevice::new(vendor_id, product_id).expect("cannot find device"); -let mut input = File::open(Path::new("/tmp/f")).expect("Cannot open file"); -device.push(&mut input, &"/data/local/tmp"); -``` - -#### (TCP) Get a shell from device - -```rust no_run -use std::net::{SocketAddr, IpAddr, Ipv4Addr}; -use adb_client::{tcp::ADBTcpDevice, ADBDeviceExt}; - -let device_ip = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 10)); -let device_port = 43210; -let mut device = ADBTcpDevice::new(SocketAddr::new(device_ip, device_port)).expect("cannot find device"); -device.shell(&mut std::io::stdin(), Box::new(std::io::stdout())); -``` diff --git a/adb_client/src/message_devices/tcp/README.md b/adb_client/src/message_devices/tcp/README.md new file mode 100644 index 00000000..cc24b1fd --- /dev/null +++ b/adb_client/src/message_devices/tcp/README.md @@ -0,0 +1,13 @@ +# Examples + +## Get a shell from device + +```rust no_run +use std::net::{SocketAddr, IpAddr, Ipv4Addr}; +use adb_client::{tcp::ADBTcpDevice, ADBDeviceExt}; + +let device_ip = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 10)); +let device_port = 43210; +let mut device = ADBTcpDevice::new(SocketAddr::new(device_ip, device_port)).expect("cannot find device"); +device.shell(&mut std::io::stdin(), Box::new(std::io::stdout())); +``` diff --git a/adb_client/src/message_devices/tcp/mod.rs b/adb_client/src/message_devices/tcp/mod.rs index cd9a81dc..17b12674 100644 --- a/adb_client/src/message_devices/tcp/mod.rs +++ b/adb_client/src/message_devices/tcp/mod.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("./README.md")] + mod adb_tcp_device; mod tcp_transport; diff --git a/adb_client/src/message_devices/usb/README.md b/adb_client/src/message_devices/usb/README.md new file mode 100644 index 00000000..bc9bfd9b --- /dev/null +++ b/adb_client/src/message_devices/usb/README.md @@ -0,0 +1,26 @@ +# Examples + +## Launch a command on device + +```rust no_run +use adb_client::{usb::ADBUSBDevice, ADBDeviceExt}; + +let vendor_id = 0x04e8; +let product_id = 0x6860; +let mut device = ADBUSBDevice::new(vendor_id, product_id).expect("cannot find device"); +device.shell_command(&["df", "-h"], &mut std::io::stdout()); +``` + +## Push a file to the device + +```rust no_run +use adb_client::{usb::ADBUSBDevice, ADBDeviceExt}; +use std::fs::File; +use std::path::Path; + +let vendor_id = 0x04e8; +let product_id = 0x6860; +let mut device = ADBUSBDevice::new(vendor_id, product_id).expect("cannot find device"); +let mut input = File::open(Path::new("/tmp/file.txt")).expect("Cannot open file"); +device.push(&mut input, &"/data/local/tmp"); +``` diff --git a/adb_client/src/message_devices/usb/mod.rs b/adb_client/src/message_devices/usb/mod.rs index 29d3490c..6463a938 100644 --- a/adb_client/src/message_devices/usb/mod.rs +++ b/adb_client/src/message_devices/usb/mod.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("./README.md")] + mod adb_rsa_key; mod adb_usb_device; mod usb_transport; diff --git a/adb_client/src/server/README.md b/adb_client/src/server/README.md new file mode 100644 index 00000000..845da978 --- /dev/null +++ b/adb_client/src/server/README.md @@ -0,0 +1,15 @@ +# Examples + +## Get available ADB devices + +```rust no_run +use adb_client::server::ADBServer; +use std::net::{SocketAddrV4, Ipv4Addr}; + +// A custom server address can be provided +let server_ip = Ipv4Addr::new(127, 0, 0, 1); +let server_port = 5037; + +let mut server = ADBServer::new(SocketAddrV4::new(server_ip, server_port)); +server.devices(); +``` diff --git a/adb_client/src/server/mod.rs b/adb_client/src/server/mod.rs index 30d73410..a47dfe27 100644 --- a/adb_client/src/server/mod.rs +++ b/adb_client/src/server/mod.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("./README.md")] + mod adb_server; mod adb_server_command; mod commands; diff --git a/adb_client/src/server_device/README.md b/adb_client/src/server_device/README.md new file mode 100644 index 00000000..27bf6216 --- /dev/null +++ b/adb_client/src/server_device/README.md @@ -0,0 +1,25 @@ +# Examples + +## Launch a command on device + +```rust no_run +use adb_client::{server::ADBServer, ADBDeviceExt}; + +let mut server = ADBServer::default(); +let mut device = server.get_device().expect("cannot get device"); +device.shell_command(&["df", "-h"], &mut std::io::stdout()); +``` + +## Push a file to the device + +```rust no_run +use adb_client::server::ADBServer; +use std::net::Ipv4Addr; +use std::fs::File; +use std::path::Path; + +let mut server = ADBServer::default(); +let mut device = server.get_device().expect("cannot get device"); +let mut input = File::open(Path::new("/tmp/file.txt")).expect("Cannot open file"); +device.push(&mut input, "/data/local/tmp"); +``` diff --git a/adb_client/src/server_device/mod.rs b/adb_client/src/server_device/mod.rs index c7830011..286c69d6 100644 --- a/adb_client/src/server_device/mod.rs +++ b/adb_client/src/server_device/mod.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("./README.md")] + mod adb_server_device; mod adb_server_device_commands; mod commands; From b916bafa5ae50ae2ff5c3d70f77dfdd3aa21b9cf Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Sun, 21 Sep 2025 10:25:19 +0200 Subject: [PATCH 11/11] feat: rework usb backend --- adb_cli/Cargo.toml | 2 +- adb_client/Cargo.toml | 2 +- adb_client/README.md | 2 +- adb_client/src/adb_device_ext.rs | 5 +- adb_client/src/error.rs | 12 +-- adb_client/src/message_devices/mod.rs | 2 - .../src/message_devices/tcp/tcp_transport.rs | 2 +- adb_client/src/message_devices/usb/README.md | 2 +- .../src/message_devices/usb/adb_usb_device.rs | 101 +++--------------- .../src/message_devices/usb/backends/mod.rs | 3 + .../rusb_transport.rs} | 19 ++-- adb_client/src/message_devices/usb/mod.rs | 55 +++++++++- adb_client/src/message_devices/usb/utils.rs | 101 ++++++++++++++++++ adb_client/src/server_device/README.md | 2 +- 14 files changed, 196 insertions(+), 114 deletions(-) create mode 100644 adb_client/src/message_devices/usb/backends/mod.rs rename adb_client/src/message_devices/usb/{usb_transport.rs => backends/rusb_transport.rs} (95%) create mode 100644 adb_client/src/message_devices/usb/utils.rs diff --git a/adb_cli/Cargo.toml b/adb_cli/Cargo.toml index 291062bc..1f958c64 100644 --- a/adb_cli/Cargo.toml +++ b/adb_cli/Cargo.toml @@ -11,7 +11,7 @@ rust-version.workspace = true version.workspace = true [dependencies] -adb_client = { version = "^2.1.17" } +adb_client = { version = "^2.1.17", features = ["mdns", "rusb"] } anyhow = { version = "1.0.100" } clap = { version = "4.5.49", features = ["derive"] } env_logger = { version = "0.11.8" } diff --git a/adb_client/Cargo.toml b/adb_client/Cargo.toml index 80c55d57..197bb7ef 100644 --- a/adb_client/Cargo.toml +++ b/adb_client/Cargo.toml @@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [] mdns = ["dep:mdns-sd"] -usb = ["dep:rsa", "dep:rusb"] +rusb = ["dep:rsa", "dep:rusb"] [dependencies] base64 = { version = "0.22.1" } diff --git a/adb_client/README.md b/adb_client/README.md index cc01cc97..2664051c 100644 --- a/adb_client/README.md +++ b/adb_client/README.md @@ -21,7 +21,7 @@ adb_client = "*" | Feature | Description | Default? | | :-----: | :---------------------------------------------: | :------: | | `mdns` | Enables mDNS device discovery on local network. | No | -| `usb` | Enables interactions with USB devices. | No | +| `rusb` | Enables interactions with USB devices. | No | To deactivate some features you can use the `default-features = false` option in your `Cargo.toml` file and manually specify the features you want to activate: diff --git a/adb_client/src/adb_device_ext.rs b/adb_client/src/adb_device_ext.rs index 9fd4d1a3..962ccaad 100644 --- a/adb_client/src/adb_device_ext.rs +++ b/adb_client/src/adb_device_ext.rs @@ -6,7 +6,10 @@ use image::{ImageBuffer, ImageFormat, Rgba}; use crate::models::AdbStatResponse; use crate::{RebootType, Result}; -/// Trait representing all features available on both [`crate::server_device::ADBServerDevice`] and [`crate::usb::ADBUSBDevice`] +/// Trait representing all features available on an ADB device, currently used by: +/// - [`crate::server_device::ADBServerDevice`] +/// - [`crate::usb::ADBUSBDevice`] +/// - [`crate::tcp::ADBTcpDevice`] pub trait ADBDeviceExt { /// Runs command in a shell on the device, and write its output and error streams into output. fn shell_command(&mut self, command: &[&str], output: &mut dyn Write) -> Result<()>; diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index c810de43..ba650ef3 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -70,8 +70,8 @@ pub enum RustADBError { #[error("Cannot get home directory")] NoHomeDirectory, /// Generic USB error - #[cfg(feature = "usb")] - #[cfg_attr(docsrs, doc(cfg(feature = "usb")))] + #[cfg(feature = "rusb")] + #[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] #[error("USB Error: {0}")] UsbError(#[from] rusb::Error), /// USB device not found @@ -90,8 +90,8 @@ pub enum RustADBError { #[error(transparent)] Base64EncodeError(#[from] base64::EncodeSliceError), /// An error occurred with RSA engine - #[cfg(feature = "usb")] - #[cfg_attr(docsrs, doc(cfg(feature = "usb")))] + #[cfg(feature = "rusb")] + #[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] #[error(transparent)] RSAError(#[from] rsa::errors::Error), /// Cannot convert given data from slice @@ -101,8 +101,8 @@ pub enum RustADBError { #[error("wrong file extension: {0}")] WrongFileExtension(String), /// An error occurred with PKCS8 data - #[cfg(feature = "usb")] - #[cfg_attr(docsrs, doc(cfg(feature = "usb")))] + #[cfg(feature = "rusb")] + #[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] #[error("error with pkcs8: {0}")] RsaPkcs8Error(#[from] rsa::pkcs8::Error), /// Error during certificate generation diff --git a/adb_client/src/message_devices/mod.rs b/adb_client/src/message_devices/mod.rs index f7a105d7..42a2f098 100644 --- a/adb_client/src/message_devices/mod.rs +++ b/adb_client/src/message_devices/mod.rs @@ -1,6 +1,4 @@ /// USB-related definitions -#[cfg(feature = "usb")] -#[cfg_attr(docsrs, doc(cfg(feature = "usb")))] pub mod usb; /// Device reachable over TCP related definition diff --git a/adb_client/src/message_devices/tcp/tcp_transport.rs b/adb_client/src/message_devices/tcp/tcp_transport.rs index ef628617..09fa2f92 100644 --- a/adb_client/src/message_devices/tcp/tcp_transport.rs +++ b/adb_client/src/message_devices/tcp/tcp_transport.rs @@ -79,7 +79,7 @@ impl Write for CurrentConnection { } } -/// Transport running on USB +/// Transport running on TCP #[derive(Clone, Debug)] pub struct TcpTransport { address: SocketAddr, diff --git a/adb_client/src/message_devices/usb/README.md b/adb_client/src/message_devices/usb/README.md index bc9bfd9b..c1414c1e 100644 --- a/adb_client/src/message_devices/usb/README.md +++ b/adb_client/src/message_devices/usb/README.md @@ -21,6 +21,6 @@ use std::path::Path; let vendor_id = 0x04e8; let product_id = 0x6860; let mut device = ADBUSBDevice::new(vendor_id, product_id).expect("cannot find device"); -let mut input = File::open(Path::new("/tmp/file.txt")).expect("Cannot open file"); +let mut input = File::open("/tmp/file.txt").expect("Cannot open file"); device.push(&mut input, &"/data/local/tmp"); ``` diff --git a/adb_client/src/message_devices/usb/adb_usb_device.rs b/adb_client/src/message_devices/usb/adb_usb_device.rs index 5ca2a5d9..7368132d 100644 --- a/adb_client/src/message_devices/usb/adb_usb_device.rs +++ b/adb_client/src/message_devices/usb/adb_usb_device.rs @@ -1,12 +1,6 @@ -use rusb::Device; -use rusb::DeviceDescriptor; -use rusb::UsbContext; -use rusb::constants::LIBUSB_CLASS_VENDOR_SPEC; -use std::fs::read_to_string; use std::io::Read; use std::io::Write; -use std::path::Path; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::time::Duration; use crate::ADBDeviceExt; @@ -18,92 +12,20 @@ use crate::message_devices::adb_message_transport::ADBMessageTransport; use crate::message_devices::adb_transport_message::ADBTransportMessage; use crate::message_devices::message_commands::MessageCommand; use crate::usb::adb_rsa_key::ADBRsaKey; -use crate::usb::usb_transport::USBTransport; +use crate::usb::backends::rusb_transport::RusbTransport; +use crate::usb::{read_adb_private_key, search_adb_devices}; use crate::utils::get_default_adb_key_path; const AUTH_TOKEN: u32 = 1; const AUTH_SIGNATURE: u32 = 2; const AUTH_RSAPUBLICKEY: u32 = 3; -pub fn read_adb_private_key>(private_key_path: P) -> Result> { - // Try to read the private key file from given path - // If the file is not found, return None - // If there is another error while reading the file, return this error - // Else, return the private key content - let pk = match read_to_string(private_key_path.as_ref()) { - Ok(pk) => pk, - Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(None), - Err(e) => return Err(e.into()), - }; - - match ADBRsaKey::new_from_pkcs8(&pk) { - Ok(pk) => Ok(Some(pk)), - Err(e) => Err(e), - } -} - -/// Search for adb devices with known interface class and subclass values -pub fn search_adb_devices() -> Result> { - let mut found_devices = vec![]; - for device in rusb::devices()?.iter() { - let Ok(des) = device.device_descriptor() else { - continue; - }; - if is_adb_device(&device, &des) { - log::debug!( - "Autodetect device {:04x}:{:04x}", - des.vendor_id(), - des.product_id() - ); - found_devices.push((des.vendor_id(), des.product_id())); - } - } - - match (found_devices.first(), found_devices.get(1)) { - (None, _) => Ok(None), - (Some(identifiers), None) => Ok(Some(*identifiers)), - (Some((vid1, pid1)), Some((vid2, pid2))) => Err(RustADBError::DeviceNotFound(format!( - "Found two Android devices {vid1:04x}:{pid1:04x} and {vid2:04x}:{pid2:04x}", - ))), - } -} - -/// Check whether a device with given descriptor is an ADB device -pub fn is_adb_device(device: &Device, des: &DeviceDescriptor) -> bool { - const ADB_SUBCLASS: u8 = 0x42; - const ADB_PROTOCOL: u8 = 0x1; - - // Some devices require choosing the file transfer mode - // for usb debugging to take effect. - const BULK_CLASS: u8 = 0xdc; - const BULK_ADB_SUBCLASS: u8 = 2; - - for n in 0..des.num_configurations() { - let Ok(config_des) = device.config_descriptor(n) else { - continue; - }; - for interface in config_des.interfaces() { - for interface_des in interface.descriptors() { - let proto = interface_des.protocol_code(); - let class = interface_des.class_code(); - let subcl = interface_des.sub_class_code(); - if proto == ADB_PROTOCOL - && ((class == LIBUSB_CLASS_VENDOR_SPEC && subcl == ADB_SUBCLASS) - || (class == BULK_CLASS && subcl == BULK_ADB_SUBCLASS)) - { - return true; - } - } - } - } - false -} - +/// Implement Android USB device /// Represent a device reached and available over USB. #[derive(Debug)] pub struct ADBUSBDevice { private_key: ADBRsaKey, - inner: ADBMessageDevice, + inner: ADBMessageDevice, } impl ADBUSBDevice { @@ -118,12 +40,15 @@ impl ADBUSBDevice { product_id: u16, private_key_path: PathBuf, ) -> Result { - Self::new_from_transport_inner(USBTransport::new(vendor_id, product_id)?, &private_key_path) + Self::new_from_transport_inner( + RusbTransport::new(vendor_id, product_id)?, + &private_key_path, + ) } - /// Instantiate a new [`ADBUSBDevice`] from a [`USBTransport`] and an optional private key path. + /// Instantiate a new [`ADBUSBDevice`] from a [`RusbTransport`] and an optional private key path. pub fn new_from_transport( - transport: USBTransport, + transport: RusbTransport, private_key_path: Option, ) -> Result { let private_key_path = match private_key_path { @@ -135,7 +60,7 @@ impl ADBUSBDevice { } fn new_from_transport_inner( - transport: USBTransport, + transport: RusbTransport, private_key_path: &PathBuf, ) -> Result { let private_key = if let Some(private_key) = read_adb_private_key(private_key_path)? { @@ -246,7 +171,7 @@ impl ADBUSBDevice { } #[inline] - fn get_transport_mut(&mut self) -> &mut USBTransport { + fn get_transport_mut(&mut self) -> &mut RusbTransport { self.inner.get_transport_mut() } } diff --git a/adb_client/src/message_devices/usb/backends/mod.rs b/adb_client/src/message_devices/usb/backends/mod.rs new file mode 100644 index 00000000..11c0af5e --- /dev/null +++ b/adb_client/src/message_devices/usb/backends/mod.rs @@ -0,0 +1,3 @@ +#[cfg(feature = "rusb")] +#[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] +pub mod rusb_transport; diff --git a/adb_client/src/message_devices/usb/usb_transport.rs b/adb_client/src/message_devices/usb/backends/rusb_transport.rs similarity index 95% rename from adb_client/src/message_devices/usb/usb_transport.rs rename to adb_client/src/message_devices/usb/backends/rusb_transport.rs index 4d8f7789..da5accd0 100644 --- a/adb_client/src/message_devices/usb/usb_transport.rs +++ b/adb_client/src/message_devices/usb/backends/rusb_transport.rs @@ -13,6 +13,7 @@ use crate::{ adb_transport_message::{ADBTransportMessage, ADBTransportMessageHeader}, message_commands::MessageCommand, }, + usb::constants::class_codes::ADB_SUBCLASS, }; #[derive(Clone, Debug)] @@ -22,18 +23,18 @@ struct Endpoint { max_packet_size: usize, } -/// Transport running on USB +/// Transport running on USB using `rusb` as a backend. #[derive(Debug, Clone)] -pub struct USBTransport { +pub struct RusbTransport { device: Device, handle: Option>>, read_endpoint: Option, write_endpoint: Option, } -impl USBTransport { - /// Instantiate a new [`USBTransport`]. - /// Only the first device with given `vendor_id` and `product_id` is returned. +impl RusbTransport { + /// Instantiate a new [`RusbTransport`]. + /// Only the first device with given vendor_id and product_id is returned. pub fn new(vendor_id: u16, product_id: u16) -> Result { for device in rusb::devices()?.iter() { if let Ok(descriptor) = device.device_descriptor() { @@ -48,7 +49,7 @@ impl USBTransport { ))) } - /// Instantiate a new [`USBTransport`] from a [`rusb::Device`]. + /// Instantiate a new [`RusbTransport`] from a [`rusb::Device`]. /// /// Devices can be enumerated using [`rusb::devices()`] and then filtered out to get desired device. pub fn new_from_device(rusb_device: rusb::Device) -> Self { @@ -108,7 +109,7 @@ impl USBTransport { for endpoint_desc in interface_desc.endpoint_descriptors() { if endpoint_desc.transfer_type() == TransferType::Bulk && interface_desc.class_code() == LIBUSB_CLASS_VENDOR_SPEC - && interface_desc.sub_class_code() == 0x42 + && interface_desc.sub_class_code() == ADB_SUBCLASS && interface_desc.protocol_code() == 0x01 { let endpoint = Endpoint { @@ -163,7 +164,7 @@ impl USBTransport { } } -impl ADBTransport for USBTransport { +impl ADBTransport for RusbTransport { fn connect(&mut self) -> crate::Result<()> { let device = self.device.open()?; @@ -202,7 +203,7 @@ impl ADBTransport for USBTransport { } } -impl ADBMessageTransport for USBTransport { +impl ADBMessageTransport for RusbTransport { fn write_message_with_timeout( &mut self, message: ADBTransportMessage, diff --git a/adb_client/src/message_devices/usb/mod.rs b/adb_client/src/message_devices/usb/mod.rs index 6463a938..8f76c62a 100644 --- a/adb_client/src/message_devices/usb/mod.rs +++ b/adb_client/src/message_devices/usb/mod.rs @@ -1,8 +1,59 @@ #![doc = include_str!("./README.md")] +/// Common USB constants for Android Debug Bridge +pub mod constants { + /// Standard Android vendor ID + pub const ANDROID_VENDOR_ID: u16 = 0x18d1; + + /// Common ADB product IDs + pub mod product_ids { + /// ADB interface + pub const ADB: u16 = 0x4ee7; + /// ADB + MTP + pub const ADB_MTP: u16 = 0x4ee2; + /// ADB + RNDIS + pub const ADB_RNDIS: u16 = 0x4ee4; + /// Fastboot interface + pub const FASTBOOT: u16 = 0x4ee0; + } + + /// USB class codes for ADB detection + pub mod class_codes { + /// ADB subclass code + pub const ADB_SUBCLASS: u8 = 0x42; + /// ADB protocol code + pub const ADB_PROTOCOL: u8 = 0x1; + /// Bulk transfer class + pub const BULK_CLASS: u8 = 0xdc; + /// Bulk ADB subclass + pub const BULK_ADB_SUBCLASS: u8 = 2; + } +} + +#[cfg(feature = "rusb")] mod adb_rsa_key; + +#[cfg(feature = "rusb")] mod adb_usb_device; -mod usb_transport; +mod backends; +mod utils; + +// Device implementations +#[cfg(feature = "rusb")] +#[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] pub use adb_usb_device::ADBUSBDevice; -pub use usb_transport::USBTransport; + +// Transport implementations +#[cfg(feature = "rusb")] +#[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] +pub use backends::rusb_transport::RusbTransport; + +// Utility functions +#[cfg(feature = "rusb")] +#[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] +pub use utils::read_adb_private_key; + +#[cfg(feature = "rusb")] +#[cfg_attr(docsrs, doc(cfg(feature = "rusb")))] +pub use utils::{is_adb_device, search_adb_devices}; diff --git a/adb_client/src/message_devices/usb/utils.rs b/adb_client/src/message_devices/usb/utils.rs new file mode 100644 index 00000000..b54f35a3 --- /dev/null +++ b/adb_client/src/message_devices/usb/utils.rs @@ -0,0 +1,101 @@ +//! USB utilities that are independent of specific transport implementations + +use crate::{Result, RustADBError}; +use std::fs::read_to_string; +use std::path::Path; + +#[cfg(feature = "rusb")] +use crate::usb::adb_rsa_key::ADBRsaKey; + +#[cfg(feature = "rusb")] +use rusb::{Device, DeviceDescriptor, UsbContext}; + +#[cfg(feature = "rusb")] +use rusb::constants::LIBUSB_CLASS_VENDOR_SPEC; + +use crate::usb::constants::class_codes::{ + ADB_PROTOCOL, ADB_SUBCLASS, BULK_ADB_SUBCLASS, BULK_CLASS, +}; + +/// Read an ADB private key from a file path +/// +/// Returns `Ok(None)` if the file doesn't exist, `Ok(Some(key))` if the key was successfully loaded, +/// or an error if there was a problem reading the file. +#[cfg(feature = "rusb")] +pub fn read_adb_private_key>(private_key_path: P) -> Result> { + // Try to read the private key file from given path + // If the file is not found, return None + // If there is another error while reading the file, return this error + // Else, return the private key content + let pk = match read_to_string(private_key_path.as_ref()) { + Ok(pk) => pk, + Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(None), + Err(e) => return Err(e.into()), + }; + + match ADBRsaKey::new_from_pkcs8(&pk) { + Ok(pk) => Ok(Some(pk)), + Err(e) => Err(e), + } +} + +/// Search for ADB devices connected via USB +/// +/// Returns the vendor_id and product_id of the first ADB device found, +/// or `None` if no devices are found. +#[cfg(feature = "rusb")] +pub fn search_adb_devices() -> Result> { + let mut found_devices = vec![]; + for device in rusb::devices()?.iter() { + let Ok(des) = device.device_descriptor() else { + continue; + }; + if is_adb_device(&device, &des) { + log::debug!( + "Autodetect device {:04x}:{:04x}", + des.vendor_id(), + des.product_id() + ); + found_devices.push((des.vendor_id(), des.product_id())); + } + } + + match (found_devices.first(), found_devices.get(1)) { + (None, _) => Ok(None), + (Some(identifiers), None) => Ok(Some(*identifiers)), + (Some((vid1, pid1)), Some((vid2, pid2))) => Err(RustADBError::DeviceNotFound(format!( + "Found two Android devices {vid1:04x}:{pid1:04x} and {vid2:04x}:{pid2:04x}", + ))), + } +} + +/// Check if a USB device is an ADB device +/// +/// This function inspects the device descriptor and configuration to determine +/// if it's an Android Debug Bridge device. +#[cfg(feature = "rusb")] +pub fn is_adb_device(device: &Device, des: &DeviceDescriptor) -> bool { + // Some devices require choosing the file transfer mode + // for usb debugging to take effect. + for n in 0..des.num_configurations() { + let Ok(config_des) = device.config_descriptor(n) else { + continue; + }; + + for interface in config_des.interfaces() { + for interface_des in interface.descriptors() { + let proto = interface_des.protocol_code(); + let class = interface_des.class_code(); + let subcl = interface_des.sub_class_code(); + if proto == ADB_PROTOCOL + && ((class == LIBUSB_CLASS_VENDOR_SPEC && subcl == ADB_SUBCLASS) + || (class == BULK_CLASS && subcl == BULK_ADB_SUBCLASS)) + { + return true; + } + } + } + } + + false +} diff --git a/adb_client/src/server_device/README.md b/adb_client/src/server_device/README.md index 27bf6216..c7bab3ed 100644 --- a/adb_client/src/server_device/README.md +++ b/adb_client/src/server_device/README.md @@ -20,6 +20,6 @@ use std::path::Path; let mut server = ADBServer::default(); let mut device = server.get_device().expect("cannot get device"); -let mut input = File::open(Path::new("/tmp/file.txt")).expect("Cannot open file"); +let mut input = File::open("/tmp/file.txt").expect("Cannot open file"); device.push(&mut input, "/data/local/tmp"); ```