diff --git a/adb_cli/src/adb_termios.rs b/adb_cli/src/adb_termios.rs index 319b027..836b800 100644 --- a/adb_cli/src/adb_termios.rs +++ b/adb_cli/src/adb_termios.rs @@ -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 droping ADBTermios: {e}") + log::error!("Error while dropping ADBTermios: {e}") } } } diff --git a/adb_cli/src/main.rs b/adb_cli/src/main.rs index fa12d3a..92c4e11 100644 --- a/adb_cli/src/main.rs +++ b/adb_cli/src/main.rs @@ -133,6 +133,10 @@ fn main() -> Result<()> { log::info!("Starting installation of APK {}...", path.display()); device.install(&path)?; } + DeviceCommands::Uninstall { package } => { + log::info!("Uninstalling the package {}...", package); + device.uninstall(&package)?; + } DeviceCommands::Framebuffer { path } => { device.framebuffer(&path)?; log::info!("Successfully dumped framebuffer at path {path}"); diff --git a/adb_cli/src/models/device.rs b/adb_cli/src/models/device.rs index b450486..bcaa9ce 100644 --- a/adb_cli/src/models/device.rs +++ b/adb_cli/src/models/device.rs @@ -33,6 +33,11 @@ pub enum DeviceCommands { /// Path to APK file. Extension must be ".apk" path: PathBuf, }, + /// Uninstall a package from the device + Uninstall { + /// Name of the package to uninstall + package: String, + }, /// Dump framebuffer of device Framebuffer { /// Framebuffer image destination path diff --git a/adb_client/src/adb_device_ext.rs b/adb_client/src/adb_device_ext.rs index 220d36f..9fc99a4 100644 --- a/adb_client/src/adb_device_ext.rs +++ b/adb_client/src/adb_device_ext.rs @@ -41,6 +41,9 @@ pub trait ADBDeviceExt { /// Install an APK pointed to by `apk_path` on device. fn install(&mut self, apk_path: &dyn AsRef) -> Result<()>; + /// Uninstall the package `package` from device. + fn uninstall(&mut self, package: &str) -> Result<()>; + /// Inner method requesting framebuffer from an Android device fn framebuffer_inner(&mut self) -> Result, Vec>>; diff --git a/adb_client/src/device/adb_message_device_commands.rs b/adb_client/src/device/adb_message_device_commands.rs index 4dc7bda..246e949 100644 --- a/adb_client/src/device/adb_message_device_commands.rs +++ b/adb_client/src/device/adb_message_device_commands.rs @@ -35,6 +35,10 @@ impl ADBDeviceExt for ADBMessageDevice { self.install(apk_path) } + fn uninstall(&mut self, package: &str) -> Result<()> { + self.uninstall(package) + } + fn framebuffer_inner(&mut self) -> Result, Vec>> { self.framebuffer_inner() } diff --git a/adb_client/src/device/adb_tcp_device.rs b/adb_client/src/device/adb_tcp_device.rs index e82d929..b535107 100644 --- a/adb_client/src/device/adb_tcp_device.rs +++ b/adb_client/src/device/adb_tcp_device.rs @@ -96,6 +96,11 @@ impl ADBDeviceExt for ADBTcpDevice { self.inner.install(apk_path) } + #[inline] + fn uninstall(&mut self, package: &str) -> Result<()> { + self.inner.uninstall(package) + } + #[inline] fn framebuffer_inner(&mut self) -> Result, Vec>> { self.inner.framebuffer_inner() diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/device/adb_usb_device.rs index 5467d6f..46661c7 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/device/adb_usb_device.rs @@ -273,6 +273,11 @@ impl ADBDeviceExt for ADBUSBDevice { self.inner.install(apk_path) } + #[inline] + fn uninstall(&mut self, package: &str) -> Result<()> { + self.inner.uninstall(package) + } + #[inline] fn framebuffer_inner(&mut self) -> Result, Vec>> { self.inner.framebuffer_inner() diff --git a/adb_client/src/device/commands/mod.rs b/adb_client/src/device/commands/mod.rs index 875f710..d1d3de3 100644 --- a/adb_client/src/device/commands/mod.rs +++ b/adb_client/src/device/commands/mod.rs @@ -5,3 +5,4 @@ mod push; mod reboot; mod shell; mod stat; +mod uninstall; diff --git a/adb_client/src/device/commands/uninstall.rs b/adb_client/src/device/commands/uninstall.rs new file mode 100644 index 0000000..b7d2632 --- /dev/null +++ b/adb_client/src/device/commands/uninstall.rs @@ -0,0 +1,19 @@ +use crate::{device::adb_message_device::ADBMessageDevice, ADBMessageTransport, Result}; + +impl ADBMessageDevice { + pub(crate) fn uninstall(&mut self, package_name: &str) -> Result<()> { + self.open_session(format!("exec:cmd package 'uninstall' {}\0", package_name).as_bytes())?; + + let final_status = self.get_transport_mut().read_message()?; + + match final_status.into_payload().as_slice() { + b"Success\n" => { + log::info!("Package {} successfully uninstalled", package_name); + Ok(()) + } + d => Err(crate::RustADBError::ADBRequestFailed(String::from_utf8( + d.to_vec(), + )?)), + } + } +} diff --git a/adb_client/src/models/adb_server_command.rs b/adb_client/src/models/adb_server_command.rs index 1782726..71fdd7d 100644 --- a/adb_client/src/models/adb_server_command.rs +++ b/adb_client/src/models/adb_server_command.rs @@ -20,6 +20,7 @@ pub(crate) enum AdbServerCommand { MDNSServices, ServerStatus, ReconnectOffline, + Uninstall(String), Install(u64), // Local commands ShellCommand(String), @@ -83,6 +84,9 @@ impl Display for AdbServerCommand { } AdbServerCommand::Usb => write!(f, "usb:"), AdbServerCommand::Install(size) => write!(f, "exec:cmd package 'install' -S {size}"), + AdbServerCommand::Uninstall(package) => { + write!(f, "exec:cmd package 'uninstall' {package}") + } } } } 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 e0eed63..d87ab51 100644 --- a/adb_client/src/server_device/adb_server_device_commands.rs +++ b/adb_client/src/server_device/adb_server_device_commands.rs @@ -115,6 +115,10 @@ impl ADBDeviceExt for ADBServerDevice { self.install(apk_path) } + fn uninstall(&mut self, package: &str) -> Result<()> { + self.uninstall(package) + } + fn framebuffer_inner(&mut self) -> Result, Vec>> { self.framebuffer_inner() } diff --git a/adb_client/src/server_device/commands/mod.rs b/adb_client/src/server_device/commands/mod.rs index 40010b8..5714bfa 100644 --- a/adb_client/src/server_device/commands/mod.rs +++ b/adb_client/src/server_device/commands/mod.rs @@ -12,4 +12,5 @@ mod send; mod stat; mod tcpip; mod transport; +mod uninstall; mod usb; diff --git a/adb_client/src/server_device/commands/uninstall.rs b/adb_client/src/server_device/commands/uninstall.rs new file mode 100644 index 0000000..9e32ba4 --- /dev/null +++ b/adb_client/src/server_device/commands/uninstall.rs @@ -0,0 +1,28 @@ +use std::io::Read; + +use crate::{models::AdbServerCommand, server_device::ADBServerDevice, Result}; + +impl ADBServerDevice { + /// Uninstall a package from device + pub fn uninstall(&mut self, package_name: &str) -> Result<()> { + let serial: String = self.identifier.clone(); + self.connect()? + .send_adb_request(AdbServerCommand::TransportSerial(serial))?; + + self.transport + .send_adb_request(AdbServerCommand::Uninstall(package_name.to_string()))?; + + let mut data = [0; 1024]; + let read_amount = self.transport.get_raw_connection()?.read(&mut data)?; + + match &data[0..read_amount] { + b"Success\n" => { + log::info!("Package {} successfully uninstalled", package_name); + Ok(()) + } + d => Err(crate::RustADBError::ADBRequestFailed(String::from_utf8( + d.to_vec(), + )?)), + } + } +}