Skip to content
Open
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
48 changes: 31 additions & 17 deletions droidrun/agent/droid/droid_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
flush,
)
from droidrun.tools.driver.android import AndroidDriver
from droidrun.tools.driver.android_ssh import AndroidSSHDriver
from droidrun.tools.driver.base import DeviceDisconnectedError
from droidrun.tools.driver.ios import IOSDriver
from droidrun.tools.driver.recording import RecordingDriver
Expand Down Expand Up @@ -407,23 +408,36 @@ async def start_handler(
driver = IOSDriver(url=ios_url)
await driver.connect()
else:
device_serial = self.resolved_device_config.serial
if device_serial is None:
devices = await adb.list()
if not devices:
raise ValueError("No connected Android devices found.")
device_serial = devices[0].serial

# Auto-setup portal if enabled
if self.config.device.auto_setup:
device_obj = await adb.device(serial=device_serial)
await ensure_portal_ready(device_obj, debug=self.config.logging.debug)

driver = AndroidDriver(
serial=device_serial,
use_tcp=self.resolved_device_config.use_tcp,
)
await driver.connect()
# Check if using SSH driver
if self.resolved_device_config.driver_type == "ssh":
driver = AndroidSSHDriver(
target=self.resolved_device_config.ssh_target,
portal_url=self.resolved_device_config.portal_url,
portal_token=self.resolved_device_config.portal_token,
su_path=self.resolved_device_config.su_path,
)
await driver.connect()
else:
# ADB driver (default)
device_serial = self.resolved_device_config.serial
if device_serial is None:
devices = await adb.list()
if not devices:
raise ValueError("No connected Android devices found.")
device_serial = devices[0].serial

# Auto-setup portal if enabled (skip for SSH mode)
if self.config.device.auto_setup:
device_obj = await adb.device(serial=device_serial)
await ensure_portal_ready(
device_obj, debug=self.config.logging.debug
)

driver = AndroidDriver(
serial=device_serial,
use_tcp=self.resolved_device_config.use_tcp,
)
await driver.connect()

# Wrap with StealthDriver if stealth mode enabled
stealth_enabled = self.config.tools and self.config.tools.stealth
Expand Down
19 changes: 19 additions & 0 deletions droidrun/config_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,25 @@ device:
platform: android
# Auto-install/update Portal APK and enable accessibility before each run
auto_setup: true

# Driver type: "adb" (default) or "ssh"
# ADB mode: Requires ADB connection (USB or TCP)
# SSH mode: Connects via SSH to device, requires Portal HTTP server
driver_type: adb

# SSH driver configuration (only used when driver_type: ssh)
# SSH target: hostname from ~/.ssh/config or user@ip
ssh_target: null # e.g., "redmi9" or "user@192.168.1.100"

# Portal HTTP server URL (only used when driver_type: ssh)
portal_url: null # e.g., "http://192.168.1.100:8080"

# Portal Bearer token for authentication (only used when driver_type: ssh)
portal_token: "" # e.g., "YOUR_TOKEN"

# Path to su binary on device (only used when driver_type: ssh)
# Default: "/debug_ramdisk/su" for rooted devices with debug_ramdisk
su_path: /debug_ramdisk/su

# === Telemetry Settings ===
telemetry:
Expand Down
11 changes: 11 additions & 0 deletions droidrun/config_manager/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ class DeviceConfig:
platform: str = "android" # "android" or "ios"
auto_setup: bool = True # auto-install/fix portal before each run

# SSH driver configuration
driver_type: str = "adb" # "adb" or "ssh"
ssh_target: Optional[str] = (
None # SSH target (e.g., "redmi9" or "user@192.168.1.100")
)
portal_url: Optional[str] = (
None # Portal HTTP URL (e.g., "http://192.168.1.100:8080")
)
portal_token: str = "" # Portal Bearer token
su_path: str = "/debug_ramdisk/su" # Path to su binary on device


@dataclass
class TelemetryConfig:
Expand Down
8 changes: 7 additions & 1 deletion droidrun/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
from droidrun.tools import AndroidDriver, RecordingDriver, UIState, StateProvider
"""

from droidrun.tools.driver import AndroidDriver, DeviceDriver, RecordingDriver
from droidrun.tools.driver import (
AndroidDriver,
DeviceDriver,
RecordingDriver,
AndroidSSHDriver,
)
from droidrun.tools.ui import AndroidStateProvider, StateProvider, UIState

__all__ = [
"DeviceDriver",
"AndroidDriver",
"RecordingDriver",
"AndroidSSHDriver",
"UIState",
"StateProvider",
"AndroidStateProvider",
Expand Down
3 changes: 2 additions & 1 deletion droidrun/tools/android/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Android tools."""

from .portal_client import PortalClient
from .portal_client_http import PortalClientHTTP

__all__ = ["PortalClient"]
__all__ = ["PortalClient", "PortalClientHTTP"]
Loading
Loading