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

feat: make ADBDeviceExt dyn-compatible #70

Merged
merged 3 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
18 changes: 3 additions & 15 deletions adb_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod adb_termios;

mod commands;
mod models;
mod utils;

use adb_client::{
ADBDeviceExt, ADBEmulatorDevice, ADBServer, ADBTcpDevice, ADBUSBDevice, DeviceShort,
Expand All @@ -17,25 +18,12 @@ use models::{Command, Opts};
use std::fs::File;
use std::io::Write;
use std::path::Path;
use utils::setup_logger;

fn main() -> Result<()> {
let opts = Opts::parse();

// RUST_LOG variable has more priority then "--debug" flag
if std::env::var("RUST_LOG").is_err() {
let level = match opts.debug {
true => "trace",
false => "info",
};

std::env::set_var("RUST_LOG", level);
}

// Setting default log level as "info" if not set
if std::env::var("RUST_LOG").is_err() {
std::env::set_var("RUST_LOG", "info");
}
env_logger::init();
setup_logger(opts.debug);

match opts.command {
Command::Local(local) => {
Expand Down
17 changes: 17 additions & 0 deletions adb_cli/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pub 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",
};

std::env::set_var("RUST_LOG", level);
}

// Setting default log level as "info" if not set
if std::env::var("RUST_LOG").is_err() {
std::env::set_var("RUST_LOG", "info");
}
cli-s1n marked this conversation as resolved.
Show resolved Hide resolved
env_logger::init();
}
47 changes: 39 additions & 8 deletions adb_client/src/adb_device_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::io::{Read, Seek, Write};
use std::path::Path;

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

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

Expand All @@ -11,27 +13,38 @@ pub trait ADBDeviceExt {
&mut self,
command: impl IntoIterator<Item = S>,
output: W,
) -> Result<()>;
) -> Result<()>
where
Self: Sized;

/// Starts an interactive shell session on the device.
/// Input data is read from reader and write to writer.
/// W has a 'static bound as it is internally used in a thread.
fn shell<R: Read, W: Write + Send + 'static>(&mut self, reader: R, writer: W) -> Result<()>;
fn shell<R: Read, W: Write + Send + 'static>(&mut self, reader: R, writer: W) -> Result<()>
where
Self: Sized;

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

/// Pull the remote file pointed to by `source` and write its contents into `output`
fn pull<A: AsRef<str>, W: Write>(&mut self, source: A, output: W) -> Result<()>;
fn pull<A: AsRef<str>, W: Write>(&mut self, source: A, output: W) -> Result<()>
where
Self: Sized;

/// Push `stream` to `path` on the device.
fn push<R: Read, A: AsRef<str>>(&mut self, stream: R, path: A) -> Result<()>;
fn push<R: Read, A: AsRef<str>>(&mut self, stream: R, path: A) -> Result<()>
where
Self: Sized;

/// 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: &str, activity: &str) -> Result<Vec<u8>>
where
Self: Sized,
{
let mut output = Vec::new();
self.shell_command(
["am", "start", &format!("{package}/{package}.{activity}")],
Expand All @@ -42,13 +55,31 @@ pub trait ADBDeviceExt {
}

/// Install an APK pointed to by `apk_path` on device.
fn install<P: AsRef<Path>>(&mut self, apk_path: P) -> Result<()>;
fn install<P: AsRef<Path>>(&mut self, apk_path: P) -> Result<()>
where
Self: Sized;

/// Inner method requesting framebuffer from an Android device
fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>>;

/// Dump framebuffer of this device into given path
fn framebuffer<P: AsRef<Path>>(&mut self, path: P) -> Result<()>;
fn framebuffer<P: AsRef<Path>>(&mut self, path: P) -> Result<()>
where
Self: Sized,
{
// Big help from AOSP source code (<https://android.googlesource.com/platform/system/adb/+/refs/heads/main/framebuffer_service.cpp>)
let img = self.framebuffer_inner()?;
Ok(img.save(path.as_ref())?)
}

/// Dump framebuffer of this device and return corresponding bytes.
///
/// Output data format is currently only `PNG`.
fn framebuffer_bytes<W: Write + Seek>(&mut self, writer: W) -> Result<()>;
fn framebuffer_bytes<W: Write + Seek>(&mut self, mut writer: W) -> Result<()>
where
Self: Sized,
{
let img = self.framebuffer_inner()?;
Ok(img.write_to(&mut writer, ImageFormat::Png)?)
}
}
8 changes: 2 additions & 6 deletions adb_client/src/device/adb_message_device_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ impl<T: ADBMessageTransport> ADBDeviceExt for ADBMessageDevice<T> {
self.install(apk_path)
}

fn framebuffer<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<()> {
self.framebuffer(path)
}

fn framebuffer_bytes<W: Write + std::io::Seek>(&mut self, writer: W) -> Result<()> {
self.framebuffer_bytes(writer)
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
self.framebuffer_inner()
}
}
9 changes: 2 additions & 7 deletions adb_client/src/device/adb_tcp_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,8 @@ impl ADBDeviceExt for ADBTcpDevice {
}

#[inline]
fn framebuffer<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
self.inner.framebuffer(path)
}

#[inline]
fn framebuffer_bytes<W: std::io::Write + std::io::Seek>(&mut self, writer: W) -> Result<()> {
self.inner.framebuffer_bytes(writer)
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
self.inner.framebuffer_inner()
}
}

Expand Down
9 changes: 2 additions & 7 deletions adb_client/src/device/adb_usb_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,8 @@ impl ADBDeviceExt for ADBUSBDevice {
}

#[inline]
fn framebuffer<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
self.inner.framebuffer(path)
}

#[inline]
fn framebuffer_bytes<W: std::io::Write + std::io::Seek>(&mut self, writer: W) -> Result<()> {
self.inner.framebuffer_bytes(writer)
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
self.inner.framebuffer_inner()
}
}

Expand Down
16 changes: 3 additions & 13 deletions adb_client/src/device/commands/framebuffer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io::{Cursor, Read, Write};
use std::io::{Cursor, Read};

use byteorder::{LittleEndian, ReadBytesExt};
use image::{ImageBuffer, ImageFormat, Rgba};
use image::{ImageBuffer, Rgba};

use crate::{
device::{adb_message_device::ADBMessageDevice, MessageCommand},
Expand All @@ -10,17 +10,7 @@ use crate::{
};

impl<T: ADBMessageTransport> ADBMessageDevice<T> {
pub fn framebuffer<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<()> {
let img = self.framebuffer_inner()?;
Ok(img.save(path.as_ref())?)
}

pub fn framebuffer_bytes<W: Write + std::io::Seek>(&mut self, mut writer: W) -> Result<()> {
let img = self.framebuffer_inner()?;
Ok(img.write_to(&mut writer, ImageFormat::Png)?)
}

fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>> {
pub(crate) fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>> {
self.open_session(b"framebuffer:\0")?;

let response = self.recv_and_reply_okay()?;
Expand Down
8 changes: 2 additions & 6 deletions adb_client/src/server_device/adb_server_device_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,7 @@ impl ADBDeviceExt for ADBServerDevice {
self.install(apk_path)
}

fn framebuffer<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
self.framebuffer(path)
}

fn framebuffer_bytes<W: Write + std::io::Seek>(&mut self, writer: W) -> Result<()> {
self.framebuffer_bytes(writer)
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
self.framebuffer_inner()
}
}
24 changes: 3 additions & 21 deletions adb_client/src/server_device/commands/framebuffer.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
use std::{
io::{Read, Seek, Write},
path::Path,
};
use std::io::Read;

use byteorder::{LittleEndian, ReadBytesExt};
use image::{ImageBuffer, ImageFormat, Rgba};
use image::{ImageBuffer, Rgba};

use crate::{
models::{AdbServerCommand, FrameBufferInfoV1, FrameBufferInfoV2},
ADBServerDevice, Result, RustADBError,
};

impl ADBServerDevice {
/// Dump framebuffer of this device into given ['path']
/// Big help from source code (<https://android.googlesource.com/platform/system/adb/+/refs/heads/main/framebuffer_service.cpp>)
pub(crate) fn framebuffer<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
let img = self.framebuffer_inner()?;
Ok(img.save(path.as_ref())?)
}

/// Dump framebuffer of this device and return corresponding bytes.
///
/// Output data format is currently only `PNG`.
pub(crate) fn framebuffer_bytes<W: Write + Seek>(&mut self, mut writer: W) -> Result<()> {
let img = self.framebuffer_inner()?;
Ok(img.write_to(&mut writer, ImageFormat::Png)?)
}

/// Inner method requesting framebuffer from Android device
fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>> {
pub(crate) fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>> {
let serial: String = self.identifier.clone();
self.connect()?
.send_adb_request(AdbServerCommand::TransportSerial(serial))?;
Expand Down
Loading