Skip to content
Draft
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
9 changes: 9 additions & 0 deletions adb_client/src/adb_device_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ pub trait ADBDeviceExt {
/// Input data is read from reader and write to writer.
fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()>;

/// Runs command on the device.
/// Input data is read from reader and write to writer.
fn exec(
&mut self,
command: &str,
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>;

Expand Down
9 changes: 9 additions & 0 deletions adb_client/src/device/adb_message_device_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ impl<T: ADBMessageTransport> ADBDeviceExt for ADBMessageDevice<T> {
self.shell(reader, writer)
}

fn exec(
&mut self,
command: &str,
reader: &mut dyn Read,
writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.exec(command, reader, writer)
}

fn stat(&mut self, remote_path: &str) -> Result<AdbStatResponse> {
self.stat(remote_path)
}
Expand Down
10 changes: 10 additions & 0 deletions adb_client/src/device/adb_tcp_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ impl ADBDeviceExt for ADBTcpDevice {
self.inner.shell(reader, writer)
}

#[inline]
fn exec(
&mut self,
command: &str,
reader: &mut dyn Read,
writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.inner.exec(command, reader, writer)
}

#[inline]
fn stat(&mut self, remote_path: &str) -> Result<crate::AdbStatResponse> {
self.inner.stat(remote_path)
Expand Down
10 changes: 10 additions & 0 deletions adb_client/src/device/adb_usb_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,16 @@ impl ADBDeviceExt for ADBUSBDevice {
self.inner.shell(reader, writer)
}

#[inline]
fn exec(
&mut self,
command: &str,
reader: &mut dyn Read,
writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.inner.exec(command, reader, writer)
}

#[inline]
fn stat(&mut self, remote_path: &str) -> Result<crate::AdbStatResponse> {
self.inner.stat(remote_path)
Expand Down
23 changes: 22 additions & 1 deletion adb_client/src/device/commands/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,31 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
/// Input data is read from [reader] and write to [writer].
pub(crate) fn shell(
&mut self,
reader: &mut dyn Read,
writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.bidi_session(b"shell:\0", reader, writer)
}

/// Runs `command` on the device.
/// Input data is read from [reader] and write to [writer].
pub(crate) fn exec(
&mut self,
command: &str,
reader: &mut dyn Read,
writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.bidi_session(format!("exec:{}\0", command).as_bytes(), reader, writer)
}

/// Starts an bidirectional(interactive) session. This can be a shell or an exec session.
fn bidi_session(
&mut self,
session_data: &[u8],
mut reader: &mut dyn Read,
mut writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.open_session(b"shell:\0")?;
self.open_session(session_data)?;

let mut transport = self.get_transport().clone();

Expand Down
2 changes: 2 additions & 0 deletions adb_client/src/models/adb_server_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(crate) enum AdbServerCommand {
// Local commands
ShellCommand(String),
Shell,
Exec(String),
FrameBuffer,
Sync,
Reboot(RebootType),
Expand Down Expand Up @@ -59,6 +60,7 @@ impl Display for AdbServerCommand {
Ok(term) => write!(f, "shell,TERM={term},raw:"),
Err(_) => write!(f, "shell,raw:"),
},
AdbServerCommand::Exec(command) => write!(f, "exec:{command}"),
AdbServerCommand::HostFeatures => write!(f, "host:features"),
AdbServerCommand::Reboot(reboot_type) => {
write!(f, "reboot:{reboot_type}")
Expand Down
70 changes: 44 additions & 26 deletions adb_client/src/server_device/adb_server_device_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,53 @@ impl ADBDeviceExt for ADBServerDevice {
self.stat(remote_path)
}

fn shell(
fn exec(
&mut self,
command: &str,
reader: &mut dyn Read,
writer: Box<(dyn Write + Send)>,
) -> Result<()> {
self.bidi_session(AdbServerCommand::Exec(command.to_owned()), reader, writer)
}

fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> {
self.bidi_session(AdbServerCommand::Shell, reader, writer)
}

fn pull(&mut self, source: &dyn AsRef<str>, mut output: &mut dyn Write) -> Result<()> {
self.pull(source, &mut output)
}

fn reboot(&mut self, reboot_type: crate::RebootType) -> Result<()> {
self.reboot(reboot_type)
}

fn push(&mut self, stream: &mut dyn Read, path: &dyn AsRef<str>) -> Result<()> {
self.push(stream, path)
}

fn install(&mut self, apk_path: &dyn AsRef<Path>) -> Result<()> {
self.install(apk_path)
}

fn uninstall(&mut self, package: &str) -> Result<()> {
self.uninstall(package)
}

fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
self.framebuffer_inner()
}
}

impl ADBServerDevice {
fn bidi_session(
&mut self,
server_cmd: AdbServerCommand,
mut reader: &mut dyn Read,
mut writer: Box<(dyn Write + Send)>,
) -> Result<()> {
// TODO: Not sure if this feature check is neccecery if server_cmd is `AdbServerCommand::Exec(_)`.
// If it isn't move this check to `<ADBServerDevice as ADBDeviceExt>::shell`.
let supported_features = self.host_features()?;
if !supported_features.contains(&HostFeatures::ShellV2)
&& !supported_features.contains(&HostFeatures::Cmd)
Expand All @@ -59,7 +101,7 @@ impl ADBDeviceExt for ADBServerDevice {
}

self.set_serial_transport()?;
self.transport.send_adb_request(AdbServerCommand::Shell)?;
self.transport.send_adb_request(server_cmd)?;

let mut read_stream = self.transport.get_raw_connection()?.try_clone()?;

Expand Down Expand Up @@ -95,28 +137,4 @@ impl ADBDeviceExt for ADBServerDevice {

Ok(())
}

fn pull(&mut self, source: &dyn AsRef<str>, mut output: &mut dyn Write) -> Result<()> {
self.pull(source, &mut output)
}

fn reboot(&mut self, reboot_type: crate::RebootType) -> Result<()> {
self.reboot(reboot_type)
}

fn push(&mut self, stream: &mut dyn Read, path: &dyn AsRef<str>) -> Result<()> {
self.push(stream, path)
}

fn install(&mut self, apk_path: &dyn AsRef<Path>) -> Result<()> {
self.install(apk_path)
}

fn uninstall(&mut self, package: &str) -> Result<()> {
self.uninstall(package)
}

fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
self.framebuffer_inner()
}
}
Loading