pub struct HdcClient { /* private fields */ }Expand description
HDC client for communicating with HDC server
Implementations§
Source§impl HdcClient
impl HdcClient
Sourcepub fn channel_id(&self) -> u32
pub fn channel_id(&self) -> u32
Get the channel ID
Sourcepub fn is_connected(&self) -> bool
pub fn is_connected(&self) -> bool
Check if handshake is complete
Sourcepub async fn send_command(&mut self, command: &str) -> Result<()>
pub async fn send_command(&mut self, command: &str) -> Result<()>
Send raw command string to server
This is used for simple commands like “list targets”, “shell ls”, etc.
Sourcepub async fn read_response(&mut self) -> Result<Vec<u8>>
pub async fn read_response(&mut self) -> Result<Vec<u8>>
Read response from server
Sourcepub async fn read_response_string(&mut self) -> Result<String>
pub async fn read_response_string(&mut self) -> Result<String>
Read response as string
Sourcepub async fn shell(&mut self, cmd: &str) -> Result<String>
pub async fn shell(&mut self, cmd: &str) -> Result<String>
Execute a shell command and return output
If a device has been selected via connect_device(), the command will be
executed on that device (the device ID is set in the channel’s connectKey
during handshake). Otherwise, HDC server will return an error asking
to specify a device.
Note: Each shell command uses up the current channel. After execution, the connection is automatically re-established if a device was connected.
Sourcepub async fn list_targets(&mut self) -> Result<Vec<String>>
pub async fn list_targets(&mut self) -> Result<Vec<String>>
List connected devices/targets
Sourcepub async fn connect_device(&mut self, device_id: &str) -> Result<()>
pub async fn connect_device(&mut self, device_id: &str) -> Result<()>
Connect to a specific device
This re-establishes the connection with the specified device ID in the handshake. After calling this, all commands will be executed on the specified device.
Sourcepub async fn check_server(&mut self) -> Result<String>
pub async fn check_server(&mut self) -> Result<String>
Check server version
Sourcepub async fn target_command(
&mut self,
device_id: &str,
cmd: &str,
) -> Result<String>
pub async fn target_command( &mut self, device_id: &str, cmd: &str, ) -> Result<String>
Execute a command on a specific device
This is a convenience method that:
- Connects to the specified device (re-handshake with connectKey)
- Executes the command
Note: This changes the client’s current device setting.
Sourcepub async fn shell_on_device(
&mut self,
device_id: &str,
cmd: &str,
) -> Result<String>
pub async fn shell_on_device( &mut self, device_id: &str, cmd: &str, ) -> Result<String>
Execute a shell command on a specific device (convenience method)
This connects to the device and executes: shell <cmd>
Sourcepub async fn fport(
&mut self,
local: ForwardNode,
remote: ForwardNode,
) -> Result<String>
pub async fn fport( &mut self, local: ForwardNode, remote: ForwardNode, ) -> Result<String>
Create a port forward (fport)
Forward local traffic to remote device.
§Example
// Forward local TCP 8080 to device TCP 8081
client.fport(ForwardNode::Tcp(8080), ForwardNode::Tcp(8081)).await?;Sourcepub async fn rport(
&mut self,
remote: ForwardNode,
local: ForwardNode,
) -> Result<String>
pub async fn rport( &mut self, remote: ForwardNode, local: ForwardNode, ) -> Result<String>
Create a reverse port forward (rport)
Reserve remote traffic to local host.
§Example
// Forward device TCP 8080 to local TCP 8081
client.rport(ForwardNode::Tcp(8080), ForwardNode::Tcp(8081)).await?;Sourcepub async fn fport_list(&mut self) -> Result<Vec<String>>
pub async fn fport_list(&mut self) -> Result<Vec<String>>
List all forward/reverse tasks
Note: This command does not require a device connection. It lists forwards across all devices.
Sourcepub async fn fport_remove(&mut self, task_str: &str) -> Result<String>
pub async fn fport_remove(&mut self, task_str: &str) -> Result<String>
Remove a forward/reverse task by task string
Note: This command does not require a device connection.
§Example
client.fport_remove("tcp:8080 tcp:8081").await?;Sourcepub async fn uninstall(
&mut self,
package: &str,
options: UninstallOptions,
) -> Result<String>
pub async fn uninstall( &mut self, package: &str, options: UninstallOptions, ) -> Result<String>
Sourcepub async fn hilog(&mut self, args: Option<&str>) -> Result<String>
pub async fn hilog(&mut self, args: Option<&str>) -> Result<String>
Display device logs using hilog
This method streams logs from the device. The log stream will continue until the connection is closed or an error occurs.
§Arguments
args- Optional arguments for hilog command (e.g., “-h” for help, “-t app” for app logs)
§Example
// Display all logs
let logs = client.hilog(None).await?;
println!("{}", logs);
// Display only app logs
let app_logs = client.hilog(Some("-t app")).await?;
println!("{}", app_logs);Sourcepub async fn hilog_stream<F>(
&mut self,
args: Option<&str>,
callback: F,
) -> Result<()>
pub async fn hilog_stream<F>( &mut self, args: Option<&str>, callback: F, ) -> Result<()>
Stream hilog output continuously with a callback
This method streams logs from the device and calls the provided callback for each log chunk received. The stream continues until an error occurs or the callback returns false.
§Arguments
args- Optional arguments for hilog commandcallback- Function to call for each log chunk. Return false to stop streaming.
§Example
client.hilog_stream(None, |log_chunk| {
print!("{}", log_chunk);
true // Continue streaming
}).await?;Sourcepub async fn wait_for_device(&mut self) -> Result<String>
pub async fn wait_for_device(&mut self) -> Result<String>
Wait for any device to connect
This command blocks until at least one device is connected. If a device is already connected, it returns immediately.
§Example
// Wait for any device
let device = client.wait_for_device().await?;
println!("Device connected: {}", device);Sourcepub async fn monitor_devices<F>(
&mut self,
interval: Duration,
callback: F,
) -> Result<()>
pub async fn monitor_devices<F>( &mut self, interval: Duration, callback: F, ) -> Result<()>
Monitor device list changes with a callback
This function continuously polls the device list and calls the callback when changes are detected. The polling interval can be configured.
Note: HDC doesn’t have a native “track-devices” command like adb, so this implementation uses polling to detect changes. Each poll creates a new connection to ensure reliability.
§Arguments
interval- Polling interval (recommended: 1-3 seconds)callback- Function called when device list changes. Return false to stop monitoring.
§Example
client.monitor_devices(Duration::from_secs(2), |devices| {
println!("Device list changed:");
for device in devices {
println!(" - {}", device);
}
true // Continue monitoring
}).await?;Sourcepub async fn file_send(
&mut self,
local_path: &str,
remote_path: &str,
options: FileTransferOptions,
) -> Result<String>
pub async fn file_send( &mut self, local_path: &str, remote_path: &str, options: FileTransferOptions, ) -> Result<String>
Send file to device
Transfer a file from local path to remote device path.
§Arguments
local_path- Local file path to sendremote_path- Remote device path destinationoptions- File transfer options (timestamp, sync, compress, etc.)
§Example
let opts = FileTransferOptions::new()
.hold_timestamp(true)
.compress(true);
client.file_send("test.txt", "/data/local/tmp/test.txt", opts).await?;Sourcepub async fn file_recv(
&mut self,
remote_path: &str,
local_path: &str,
options: FileTransferOptions,
) -> Result<String>
pub async fn file_recv( &mut self, remote_path: &str, local_path: &str, options: FileTransferOptions, ) -> Result<String>
Receive file from device
Transfer a file from remote device path to local path.
§Arguments
remote_path- Remote device file path to receivelocal_path- Local destination pathoptions- File transfer options (timestamp, sync, compress, etc.)
§Example
let opts = FileTransferOptions::new().hold_timestamp(true);
client.file_recv("/data/local/tmp/test.txt", "test.txt", opts).await?;