Skip to content
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ target
/.vscode
venv
/.mypy_cache
pyadb_client/pyadb_client.pyi
pyadb_client/pyadb_client.pyi
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["adb_cli", "adb_client", "pyadb_client", "examples/mdns"]
members = ["adb_cli", "adb_client", "examples/mdns", "pyadb_client"]
resolver = "2"

[workspace.package]
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,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.
Expand Down
2 changes: 1 addition & 1 deletion adb_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ version.workspace = true
workspace = true

[dependencies]
adb_client = { version = "^2.1.19", features = ["mdns"] }
adb_client = { version = "^2.1.19", features = ["mdns", "usb"] }
clap = { version = "4.5.53", features = ["derive"] }
env_logger = { version = "0.11.8" }
log = { version = "0.4.29" }
Expand Down
2 changes: 1 addition & 1 deletion adb_cli/src/handlers/emulator_commands.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use adb_client::ADBEmulatorDevice;
use adb_client::emulator::ADBEmulatorDevice;

use crate::models::{ADBCliResult, EmuCommand, EmulatorCommand};

Expand Down
5 changes: 4 additions & 1 deletion adb_cli/src/handlers/host_commands.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down
6 changes: 3 additions & 3 deletions adb_cli/src/handlers/local_commands.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{fs::File, io::Write};

use crate::ADBCliResult;
use crate::models::LocalDeviceCommand;
use adb_client::ADBServerDevice;
use adb_client::server_device::ADBServerDevice;

use crate::models::{ADBCliResult, LocalDeviceCommand};

pub fn handle_local_commands(
mut device: ADBServerDevice,
Expand Down
24 changes: 7 additions & 17 deletions adb_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ mod handlers;
mod models;
mod utils;

use adb_client::{
ADBDeviceExt, ADBListItemType, ADBServer, ADBServerDevice, ADBTcpDevice, ADBUSBDevice,
mdns::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;
Expand Down Expand Up @@ -89,19 +91,7 @@ fn run_command(mut device: Box<dyn ADBDeviceExt>, command: DeviceCommands) -> AD
DeviceCommands::List { path } => {
let dirs = device.list(&path)?;
for dir in dirs {
let list_item_type = match dir.item_type {
ADBListItemType::File => "File".to_string(),
ADBListItemType::Directory => "Directory".to_string(),
ADBListItemType::Symlink => "Symlink".to_string(),
};
log::info!(
"type: {}, name: {}, time: {}, size: {}, permissions: {:#o}",
list_item_type,
dir.name,
dir.time,
dir.size,
dir.permissions
);
log::info!("{dir}");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion adb_cli/src/models/host.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{net::SocketAddrV4, str::FromStr};

use adb_client::{RustADBError, WaitForDeviceTransport};
use adb_client::{RustADBError, server::WaitForDeviceTransport};
use clap::Parser;

fn parse_wait_for_device_device_transport(
Expand Down
13 changes: 10 additions & 3 deletions adb_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[features]
default = []
mdns = ["dep:mdns-sd"]
usb = ["dep:rusb"]

[dependencies]
base64 = { version = "0.22.1" }
Expand All @@ -32,10 +33,12 @@ num-bigint = { version = "0.8.6", package = "num-bigint-dig" }
num-traits = { version = "0.2.19" }
quick-protobuf = { version = "0.8.1" }
rand = { version = "0.9.2" }
rcgen = { version = "0.14.6" }
rcgen = { version = "0.14.6", default-features = false, features = [
"aws_lc_rs",
"pem",
] }
regex = { version = "1.12.2", features = ["perf", "std", "unicode"] }
rsa = { version = "0.9.9" }
rusb = { version = "0.9.4", features = ["vendored"] }
rsa = { version = "0.9.7" }
rustls = { version = "0.23.35" }
rustls-pki-types = { version = "1.13.2" }
serde = { version = "1.0.228", features = ["derive"] }
Expand All @@ -49,6 +52,10 @@ mdns-sd = { version = "0.17.1", default-features = false, features = [
"logging",
], optional = true }
#########
#########
# USB-only dependencies
rusb = { version = "0.9.4", features = ["vendored"], optional = true }
#########

[dev-dependencies]
anyhow = { version = "1.0.100" }
Expand Down
90 changes: 8 additions & 82 deletions adb_client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,21 @@ adb_client = "*"
| Feature | Description | Default? |
| :-----: | :---------------------------------------------: | :------: |
| `mdns` | Enables mDNS device discovery on local network. | No |
| `usb` | Enables interactions with USB devices. | No |

To deactivate some default 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 = ["mdns"] }
adb_client = { version = "*", default-features = false, features = ["mdns", "usb"] }
```

## 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
Expand All @@ -42,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 | <div style="color:green">-1,57 %</div> |
| 500 MB | 50 | 15,60 s | 15,64 s | <div style="color:green">-0,25 %</div> |
| 1 GB | 20 | 31,09 s | 31,12 s | <div style="color:green">-0,10 %</div> |

## Examples

### Get available ADB devices

```rust no_run
use adb_client::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::{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::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::{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::{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::{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()));
```
29 changes: 21 additions & 8 deletions adb_client/src/adb_device_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use std::path::Path;

use image::{ImageBuffer, ImageFormat, Rgba};

use crate::models::AdbStatResponse;
use crate::{ADBListItem, RebootType, Result};
use crate::models::{ADBListItemType, AdbStatResponse};
use crate::{RebootType, Result};

/// Trait representing all features available on both [`crate::ADBServerDevice`] and [`crate::ADBUSBDevice`]
/// Trait representing all features available on ADB devices.
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<()>;
Expand All @@ -16,7 +16,7 @@ pub trait ADBDeviceExt {
fn shell(&mut self, reader: &mut dyn Read, writer: Box<dyn Write + Send>) -> Result<()>;

/// Display the stat information for a remote file
fn stat(&mut self, remote_path: &str) -> Result<AdbStatResponse>;
fn stat(&mut self, remote_path: &dyn AsRef<str>) -> Result<AdbStatResponse>;

/// Pull the remote file pointed to by `source` and write its contents into `output`
fn pull(&mut self, source: &dyn AsRef<str>, output: &mut dyn Write) -> Result<()>;
Expand All @@ -25,16 +25,29 @@ pub trait ADBDeviceExt {
fn push(&mut self, stream: &mut dyn Read, path: &dyn AsRef<str>) -> Result<()>;

/// List the items in a directory on the device
fn list(&mut self, path: &dyn AsRef<str>) -> Result<Vec<ADBListItem>>;
fn list(&mut self, path: &dyn AsRef<str>) -> Result<Vec<ADBListItemType>>;

/// Reboot the device using given reboot type
fn reboot(&mut self, reboot_type: RebootType) -> Result<()>;

/// Run `activity` from `package` on device. Return the command output.
fn run_activity(&mut self, package: &str, activity: &str) -> Result<Vec<u8>> {
fn run_activity(
&mut self,
package: &dyn AsRef<str>,
activity: &dyn AsRef<str>,
) -> Result<Vec<u8>> {
let mut output = Vec::new();
self.shell_command(
&["am", "start", &format!("{package}/{package}.{activity}")],
&[
"am",
"start",
&format!(
"{}/{}.{}",
package.as_ref(),
package.as_ref(),
activity.as_ref()
),
],
&mut output,
)?;

Expand All @@ -45,7 +58,7 @@ pub trait ADBDeviceExt {
fn install(&mut self, apk_path: &dyn AsRef<Path>) -> Result<()>;

/// Uninstall the package `package` from device.
fn uninstall(&mut self, package: &str) -> Result<()>;
fn uninstall(&mut self, package: &dyn AsRef<str>) -> Result<()>;

/// Inner method requesting framebuffer from an Android device
fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>>;
Expand Down
1 change: 0 additions & 1 deletion adb_client/src/constants.rs

This file was deleted.

12 changes: 0 additions & 12 deletions adb_client/src/device/commands/stat.rs

This file was deleted.

19 changes: 0 additions & 19 deletions adb_client/src/device/commands/uninstall.rs

This file was deleted.

19 changes: 0 additions & 19 deletions adb_client/src/device/mod.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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<Regex> = LazyLock::new(|| {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading
Loading