Skip to main content

Overview

Droidrun controls devices through a specialized Portal app that bridges your computer and the device.
  • Android Setup
  • iOS Setup (experimental)

Prerequisites

1

Install ADB

macOS: brew install android-platform-toolsLinux: sudo apt install adbWindows: Download from Android Developer SiteVerify: adb version
2

Enable USB Debugging

  1. Go to Settings > About phone
  2. Tap Build number 7 times (enables Developer options)
  3. Go to Settings > Developer options
  4. Enable USB debugging
  5. Connect device and tap Always allow
Verify: adb devices
3

Install Portal App

# Automatic setup (downloads latest Portal APK)
droidrun setup

# Or specify device
droidrun setup --device SERIAL_NUMBER
This will:
  • Download the latest Portal APK
  • Install with all permissions granted
  • Enable accessibility service automatically
4

Verify Setup

droidrun ping
# Output: Portal is installed and accessible. You're good to go!

Portal App

The Droidrun Portal (com.droidrun.portal) provides:
  • Accessibility Tree - Extracts UI elements and their properties
  • Device State - Tracks current activity, keyboard visibility
  • Action Execution - Tap, swipe, text input, and other actions
  • Dual Communication - TCP (faster) or Content Provider (fallback)
The Portal only communicates locally via ADB. No data is sent to external servers.

Communication Modes

How it works:
  • Portal exposes content provider at content://com.droidrun.portal/
  • Commands sent via ADB shell: content query --uri ...
  • JSON responses parsed from shell output
Usage:
# Default mode (no flag needed)
droidrun ping

# Python
tools = DeviceConfig(serial="DEVICE_SERIAL", use_tcp=False)
Troubleshooting:
# Test content provider directly
adb shell content query --uri content://com.droidrun.portal/state

# Should show: Row: 0 result={"data": "{...}"}

Advanced Setup

Setup

1

Enable Wireless Debugging

  1. Settings > Developer options > Wireless debugging
  2. Note IP address and port (e.g., 192.168.1.100:37757)
2

Pair Device (First Time)

QR Code Method:
adb pair <QR_CODE_STRING>
Pairing Code Method:
  1. Tap Pair device with pairing code
  2. Note pairing code and IP:port
  3. Run: adb pair IP:PORT
  4. Enter pairing code
3

Connect

adb connect IP:PORT
droidrun ping --device IP:PORT

Common Issues

  • Connection refused → Check same WiFi network and firewall
  • Frequent drops → Use 5GHz WiFi or stay near router
  • Can’t find IP → Run adb shell ip addr show wlan0 | grep "inet " via USB
1

Enable TCP/IP Mode (USB Required)

# Connect via USB first
adb tcpip 5555
2

Find Device IP

adb shell ip addr show wlan0 | grep inet
3

Connect Wirelessly

# Disconnect USB cable
adb connect DEVICE_IP:5555
droidrun ping --device DEVICE_IP:5555

List Devices

droidrun devices
# Found 2 connected device(s):
#   • emulator-5554
#   • 192.168.1.100:5555

Target Specific Device

# CLI
droidrun run "your command" --device emulator-5554

# Python
tools = DeviceConfig(serial="emulator-5554")
agent = DroidAgent(goal="your task", tools=tools)

Parallel Control

import asyncio
from droidrun import DeviceConfig, DroidAgent
from adbutils import adb

async def control_device(serial: str, command: str):
    device_config = DeviceConfig(serial=serial)
    agent = DroidAgent(goal=command, device_config=tools)
    return await agent.run()

async def main():
    devices = adb.list()

    tasks = [
        control_device(devices[0].serial, "Open settings"),
        control_device(devices[1].serial, "Check battery"),
    ]

    results = await asyncio.gather(*tasks)
    print(results)

asyncio.run(main())

Troubleshooting

Symptoms: adb devices shows no devices or unauthorizedSolutions:
  1. Unplug/replug USB cable, try different port
  2. Revoke USB debugging authorizations (Developer options)
  3. Reconnect and tap “Always allow”
  4. Restart ADB: adb kill-server && adb start-server
  5. Windows: Install Google USB Driver
Symptoms: droidrun ping fails with “Portal is not installed”Solutions:
  1. Reinstall: droidrun setup
  2. Check: adb shell pm list packages | grep droidrun
  3. Verify APK architecture matches device (arm64-v8a for most devices)
Symptoms: droidrun ping fails with “accessibility service not enabled”Solutions:
  1. Auto-enable:
    adb shell settings put secure enabled_accessibility_services \
      com.droidrun.portal/com.droidrun.portal.DroidrunAccessibilityService
    adb shell settings put secure accessibility_enabled 1
    
  2. Manual: Settings > Accessibility > Droidrun Portal > Toggle ON
  3. Verify:
    adb shell settings get secure enabled_accessibility_services
    # Should contain: com.droidrun.portal/...
    
Symptoms: input_text() fails or types gibberishSolutions:
  1. Keyboard auto-enabled by AdbTools.__init__():
    # Verify
    adb shell settings get secure default_input_method
    # Should show: com.droidrun.portal/.DroidrunKeyboardIME
    
  2. Manual switch: Long press space bar → Select “Droidrun Keyboard”
  3. Focus element first: tools.tap_by_index(5) then tools.input_text("text")
Symptoms: get_state() returns empty or incomplete UI treeSolutions:
  1. Verify accessibility: droidrun ping
  2. Some apps block accessibility services (WebViews, games, custom UI)
  3. Wait for UI: time.sleep(1) after tap/swipe
  4. Enable Portal overlay to see detected elements

Next Steps

I