Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: internal updates #74

Merged
merged 4 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions adb_cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,29 @@ Usage is quite simple, and tends to look like `adb`:
- To use ADB server as a proxy:

```bash
user@laptop ~/adb_client (main)> adb_cli --help
Rust ADB (Android Debug Bridge) CLI
user@laptop ~/adb_client (main)> adb_cli local --help
Device related commands using server

Usage: adb_cli [OPTIONS] <COMMAND>
Usage: adb_cli local [OPTIONS] <COMMAND>

Commands:
host-features List available server features
push Push a file on device
pull Pull a file from device
list List a directory on device
stat Stat a file specified on device
shell Spawn an interactive shell or run a list of commands on the device
pull Pull a file from device
push Push a file on device
stat Stat a file on device
run Run an activity on device specified by the intent
reboot Reboot the device
install Install an APK on device
framebuffer Dump framebuffer of device
host-features List available server features
list List a directory on device
logcat Get logs of device
version Print current ADB version
kill Ask ADB server to quit immediately
devices List connected devices
track-devices Track new devices showing up
pair Pair device with a given code
connect Connect device over WI-FI
disconnect Disconnect device over WI-FI
sms Send a SMS with given phone number and given content
rotate Rotate device screen from 90°
help Print this message or the help of the given subcommand(s)

Options:
-d, --debug
-a, --address <ADDRESS> [default: 127.0.0.1:5037]
-s, --serial <SERIAL> Serial id of a specific device. Every request will be sent to this device
-h, --help Print help
-V, --version Print version
```

- To interact directly with end devices
Expand Down
5 changes: 4 additions & 1 deletion adb_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ fn main() -> Result<()> {
log::info!("Starting installation of APK {}...", path.display());
device.install(&path)?;
}
DeviceCommands::Framebuffer { path } => device.framebuffer(&path)?,
DeviceCommands::Framebuffer { path } => {
device.framebuffer(&path)?;
log::info!("Successfully dumped framebuffer at path {path}");
}
}

Ok(())
Expand Down
14 changes: 5 additions & 9 deletions adb_client/src/device/adb_message_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,11 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
message: ADBTransportMessage,
) -> Result<ADBTransportMessage> {
self.transport.write_message(message)?;
let message = self.transport.read_message()?;
let received_command = message.header().command();
if received_command != MessageCommand::Okay {
return Err(RustADBError::ADBRequestFailed(format!(
"expected command OKAY after message, got {}",
received_command
)));
}
Ok(message)

self.transport.read_message().and_then(|message| {
message.assert_command(MessageCommand::Okay)?;
Ok(message)
})
}

pub(crate) fn recv_file<W: std::io::Write>(
Expand Down
20 changes: 7 additions & 13 deletions adb_client/src/device/adb_tcp_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{io::Read, net::SocketAddr};
use super::adb_message_device::ADBMessageDevice;
use super::models::MessageCommand;
use super::ADBTransportMessage;
use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, Result, RustADBError, TcpTransport};
use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, Result, TcpTransport};

/// Represent a device reached and available over USB.
#[derive(Debug)]
Expand Down Expand Up @@ -38,19 +38,13 @@ impl ADBTcpDevice {

self.get_transport_mut().write_message(message)?;

let message = self.get_transport_mut().read_message()?;
// At this point, we should have received a STLS command indicating that the device wants to upgrade connection with TLS
self.get_transport_mut()
.read_message()
.and_then(|message| message.assert_command(MessageCommand::Stls))?;

// At this point, we should have received a STLS message
if message.header().command() != MessageCommand::Stls {
return Err(RustADBError::ADBRequestFailed(format!(
"Wrong command received {}",
message.header().command()
)));
};

let message = ADBTransportMessage::new(MessageCommand::Stls, 1, 0, &[]);

self.get_transport_mut().write_message(message)?;
self.get_transport_mut()
.write_message(ADBTransportMessage::new(MessageCommand::Stls, 1, 0, &[]))?;

// Upgrade TCP connection to TLS
self.get_transport_mut().upgrade_connection()?;
Expand Down
18 changes: 15 additions & 3 deletions adb_client/src/device/adb_transport_message.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};

use crate::RustADBError;
use crate::{Result, RustADBError};

use super::models::MessageCommand;

Expand Down Expand Up @@ -66,7 +66,7 @@ impl ADBTransportMessageHeader {
command_u32 ^ 0xFFFFFFFF
}

pub fn as_bytes(&self) -> Result<Vec<u8>, RustADBError> {
pub fn as_bytes(&self) -> Result<Vec<u8>> {
bincode::serialize(&self).map_err(|_e| RustADBError::ConversionError)
}
}
Expand All @@ -88,6 +88,18 @@ impl ADBTransportMessage {
&& ADBTransportMessageHeader::compute_crc32(&self.payload) == self.header.data_crc32
}

pub fn assert_command(&self, expected_command: MessageCommand) -> Result<()> {
let our_command = self.header().command();
if expected_command == our_command {
return Ok(());
}

Err(RustADBError::WrongResponseReceived(
our_command.to_string(),
expected_command.to_string(),
))
}

pub fn header(&self) -> &ADBTransportMessageHeader {
&self.header
}
Expand All @@ -104,7 +116,7 @@ impl ADBTransportMessage {
impl TryFrom<[u8; 24]> for ADBTransportMessageHeader {
type Error = RustADBError;

fn try_from(value: [u8; 24]) -> Result<Self, Self::Error> {
fn try_from(value: [u8; 24]) -> Result<Self> {
bincode::deserialize(&value).map_err(|_e| RustADBError::ConversionError)
}
}
43 changes: 16 additions & 27 deletions adb_client/src/device/adb_usb_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,14 @@ impl ADBUSBDevice {
self.get_transport_mut().write_message(message)?;

let message = self.get_transport_mut().read_message()?;
message.assert_command(MessageCommand::Auth)?;

// At this point, we should have received either:
// - an AUTH message with arg0 == 1
// - a CNXN message
let auth_message = match message.header().command() {
MessageCommand::Auth if message.header().arg0() == AUTH_TOKEN => message,
MessageCommand::Auth if message.header().arg0() != AUTH_TOKEN => {
return Err(RustADBError::ADBRequestFailed(
"Received AUTH message with type != 1".into(),
))
}
c => {
// At this point, we should have receive an AUTH message with arg0 == 1
let auth_message = match message.header().arg0() {
AUTH_TOKEN => message,
v => {
return Err(RustADBError::ADBRequestFailed(format!(
"Wrong command received {}",
c
"Received AUTH message with type != 1 ({v})"
)))
}
};
Expand Down Expand Up @@ -225,20 +218,16 @@ impl ADBUSBDevice {

let response = self
.get_transport_mut()
.read_message_with_timeout(Duration::from_secs(10))?;

match response.header().command() {
MessageCommand::Cnxn => log::info!(
"Authentication OK, device info {}",
String::from_utf8(response.into_payload())?
),
_ => {
return Err(RustADBError::ADBRequestFailed(format!(
"wrong response {}",
response.header().command()
)))
}
}
.read_message_with_timeout(Duration::from_secs(10))
.and_then(|message| {
message.assert_command(MessageCommand::Cnxn)?;
Ok(message)
})?;

log::info!(
"Authentication OK, device info {}",
String::from_utf8(response.into_payload())?
);

Ok(())
}
Expand Down
13 changes: 5 additions & 8 deletions adb_client/src/device/commands/framebuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,10 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
v => return Err(RustADBError::UnimplementedFramebufferImageVersion(v)),
};

let message = self.get_transport_mut().read_message()?;
match message.header().command() {
MessageCommand::Clse => Ok(img),
c => Err(RustADBError::ADBRequestFailed(format!(
"Wrong command received {}",
c
))),
}
self.get_transport_mut()
.read_message()
.and_then(|message| message.assert_command(MessageCommand::Clse))?;

Ok(img)
}
}
12 changes: 4 additions & 8 deletions adb_client/src/device/commands/reboot.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
use crate::{
device::{adb_message_device::ADBMessageDevice, MessageCommand},
ADBMessageTransport, RebootType, Result, RustADBError,
ADBMessageTransport, RebootType, Result,
};

impl<T: ADBMessageTransport> ADBMessageDevice<T> {
pub(crate) fn reboot(&mut self, reboot_type: RebootType) -> Result<()> {
self.open_session(format!("reboot:{}\0", reboot_type).as_bytes())?;

let message = self.get_transport_mut().read_message()?;

if message.header().command() != MessageCommand::Okay {
return Err(RustADBError::ADBShellNotSupported);
}

Ok(())
self.get_transport_mut()
.read_message()
.and_then(|message| message.assert_command(MessageCommand::Okay))
}
}
23 changes: 11 additions & 12 deletions adb_client/src/device/message_writer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::io::{ErrorKind, Write};
use std::io::{Error, ErrorKind, Result, Write};

use crate::ADBMessageTransport;

Expand All @@ -24,26 +24,25 @@ impl<T: ADBMessageTransport> MessageWriter<T> {
}

impl<T: ADBMessageTransport> Write for MessageWriter<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let message =
ADBTransportMessage::new(MessageCommand::Write, self.local_id, self.remote_id, buf);
self.transport
.write_message(message)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
.map_err(|e| Error::new(ErrorKind::InvalidData, e))?;

match self.transport.read_message() {
Ok(response) => match response.header().command() {
MessageCommand::Okay => Ok(buf.len()),
c => Err(std::io::Error::new(
ErrorKind::Other,
format!("wrong response received: {c}"),
)),
},
Err(e) => Err(std::io::Error::new(ErrorKind::Other, e)),
Ok(response) => {
response
.assert_command(MessageCommand::Okay)
.map_err(|e| Error::new(ErrorKind::Other, e))?;
Ok(buf.len())
}
Err(e) => Err(Error::new(ErrorKind::Other, e)),
}
}

fn flush(&mut self) -> std::io::Result<()> {
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
2 changes: 1 addition & 1 deletion adb_client/src/emulator_device/adb_emulator_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl TryFrom<ADBServerDevice> for ADBEmulatorDevice {
fn try_from(value: ADBServerDevice) -> std::result::Result<Self, Self::Error> {
ADBEmulatorDevice::new(
value.identifier.clone(),
Some(*value.get_transport().get_socketaddr().ip()),
Some(*value.transport.get_socketaddr().ip()),
)
}
}
Expand Down
6 changes: 2 additions & 4 deletions adb_client/src/emulator_device/commands/rotate.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::{models::ADBEmulatorCommand, ADBEmulatorDevice, Result};
use crate::{emulator_device::ADBEmulatorCommand, ADBEmulatorDevice, Result};

impl ADBEmulatorDevice {
/// Send a SMS to this emulator with given content with given phone number
pub fn rotate(&mut self) -> Result<()> {
let transport = self.connect()?;
transport.send_command(ADBEmulatorCommand::Rotate)?;
Ok(())
self.connect()?.send_command(ADBEmulatorCommand::Rotate)
}
}
8 changes: 3 additions & 5 deletions adb_client/src/emulator_device/commands/sms.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use crate::{models::ADBEmulatorCommand, ADBEmulatorDevice, Result};
use crate::{emulator_device::ADBEmulatorCommand, ADBEmulatorDevice, Result};

impl ADBEmulatorDevice {
/// Send a SMS to this emulator with given content with given phone number
pub fn send_sms(&mut self, phone_number: &str, content: &str) -> Result<()> {
let transport = self.connect()?;
transport.send_command(ADBEmulatorCommand::Sms(
self.connect()?.send_command(ADBEmulatorCommand::Sms(
phone_number.to_string(),
content.to_string(),
))?;
Ok(())
))
}
}
2 changes: 2 additions & 0 deletions adb_client/src/emulator_device/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod adb_emulator_device;
mod commands;
mod models;
pub use adb_emulator_device::ADBEmulatorDevice;
pub(crate) use models::ADBEmulatorCommand;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::Display;

pub(crate) enum ADBEmulatorCommand {
pub enum ADBEmulatorCommand {
Authenticate(String),
Sms(String, String),
Rotate,
Expand Down
2 changes: 2 additions & 0 deletions adb_client/src/emulator_device/models/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod adb_emulator_command;
pub use adb_emulator_command::ADBEmulatorCommand;
3 changes: 3 additions & 0 deletions adb_client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub enum RustADBError {
/// Indicates that ADB server responded an unknown response type.
#[error("Unknown response type {0}")]
UnknownResponseType(String),
/// Indicated that an unexpected command has been received
#[error("Wrong response command received: {0}. Expected {1}")]
WrongResponseReceived(String, String),
/// Indicates that ADB server responses an unknown device state.
#[error("Unknown device state {0}")]
UnknownDeviceState(String),
Expand Down
4 changes: 1 addition & 3 deletions adb_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ pub use device::{ADBTcpDevice, ADBUSBDevice};
pub use emulator_device::ADBEmulatorDevice;
pub use error::{Result, RustADBError};
pub use mdns::*;
pub use models::{
AdbStatResponse, AdbVersion, DeviceLong, DeviceShort, DeviceState, MDNSBackend, RebootType,
};
pub use models::{AdbStatResponse, RebootType};
pub use server::*;
pub use server_device::ADBServerDevice;
pub use transports::*;
Loading
Loading