Skip to content
Merged
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
32 changes: 16 additions & 16 deletions docs/sdk/adb-tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: AndroidDriver

Raw Android device I/O via ADB + Portal.

<a id="mobilerun.tools.driver.android.AndroidDriver"></a>
<a id="mobilerun.tools.AndroidDriver"></a>

## AndroidDriver

Expand All @@ -16,7 +16,7 @@ Raw Android device I/O via ADB and the Mobilerun Portal app.

AndroidDriver provides low-level device communication for Android devices through ADB (Android Debug Bridge). It supports both TCP communication and content provider modes via the Mobilerun Portal app. AndroidDriver declares its capabilities in the `supported` set, and unsupported methods raise `NotImplementedError`.

<a id="mobilerun.tools.driver.android.AndroidDriver.__init__"></a>
<a id="mobilerun.tools.AndroidDriver.__init__"></a>

#### AndroidDriver.\_\_init\_\_

Expand Down Expand Up @@ -73,7 +73,7 @@ AndroidDriver.supported_buttons = {"back", "home", "enter"}

## Lifecycle Methods

<a id="mobilerun.tools.driver.android.AndroidDriver.connect"></a>
<a id="mobilerun.tools.AndroidDriver.connect"></a>

#### AndroidDriver.connect

Expand All @@ -90,7 +90,7 @@ driver = AndroidDriver(serial="emulator-5554")
await driver.connect()
```

<a id="mobilerun.tools.driver.android.AndroidDriver.ensure_connected"></a>
<a id="mobilerun.tools.AndroidDriver.ensure_connected"></a>

#### AndroidDriver.ensure\_connected

Expand All @@ -104,7 +104,7 @@ Connect if not already connected. Safe to call multiple times.

## Input Action Methods

<a id="mobilerun.tools.driver.android.AndroidDriver.tap"></a>
<a id="mobilerun.tools.AndroidDriver.tap"></a>

#### AndroidDriver.tap

Expand All @@ -125,7 +125,7 @@ Tap at absolute pixel coordinates on the device screen.
await driver.tap(540, 960)
```

<a id="mobilerun.tools.driver.android.AndroidDriver.swipe"></a>
<a id="mobilerun.tools.AndroidDriver.swipe"></a>

#### AndroidDriver.swipe

Expand Down Expand Up @@ -163,7 +163,7 @@ await driver.swipe(800, 960, 200, 960, duration_ms=250)
- Duration is converted to seconds internally (dividing by 1000)
- Includes an async sleep matching the swipe duration for UI settling

<a id="mobilerun.tools.driver.android.AndroidDriver.input_text"></a>
<a id="mobilerun.tools.AndroidDriver.input_text"></a>

#### AndroidDriver.input\_text

Expand Down Expand Up @@ -196,7 +196,7 @@ success = await driver.input_text("New text", clear=True)
- Uses the Mobilerun Portal app keyboard for reliable text input via PortalClient
- Supports Unicode characters and special characters

<a id="mobilerun.tools.driver.android.AndroidDriver.press_button"></a>
<a id="mobilerun.tools.AndroidDriver.press_button"></a>

#### AndroidDriver.press\_button

Expand All @@ -222,7 +222,7 @@ await driver.press_button("home")
await driver.press_button("back")
```

<a id="mobilerun.tools.driver.android.AndroidDriver.drag"></a>
<a id="mobilerun.tools.AndroidDriver.drag"></a>

#### AndroidDriver.drag

Expand Down Expand Up @@ -253,7 +253,7 @@ Drag from (x1, y1) to (x2, y2).

## App Management Methods

<a id="mobilerun.tools.driver.android.AndroidDriver.start_app"></a>
<a id="mobilerun.tools.AndroidDriver.start_app"></a>

#### AndroidDriver.start\_app

Expand Down Expand Up @@ -284,7 +284,7 @@ result = await driver.start_app("com.android.settings")
result = await driver.start_app("com.android.settings", ".Settings")
```

<a id="mobilerun.tools.driver.android.AndroidDriver.install_app"></a>
<a id="mobilerun.tools.AndroidDriver.install_app"></a>

#### AndroidDriver.install\_app

Expand All @@ -311,7 +311,7 @@ result = await driver.install_app("/path/to/app.apk")
result = await driver.install_app("/path/to/app.apk", reinstall=True)
```

<a id="mobilerun.tools.driver.android.AndroidDriver.list_packages"></a>
<a id="mobilerun.tools.AndroidDriver.list_packages"></a>

#### AndroidDriver.list\_packages

Expand All @@ -329,7 +329,7 @@ Return installed package names.

- `List[str]` - List of package names

<a id="mobilerun.tools.driver.android.AndroidDriver.get_apps"></a>
<a id="mobilerun.tools.AndroidDriver.get_apps"></a>

#### AndroidDriver.get\_apps

Expand All @@ -351,7 +351,7 @@ Return installed apps as list of dicts with 'package' and 'label' keys.

## State and Observation Methods

<a id="mobilerun.tools.driver.android.AndroidDriver.screenshot"></a>
<a id="mobilerun.tools.AndroidDriver.screenshot"></a>

#### AndroidDriver.screenshot

Expand All @@ -377,7 +377,7 @@ with open("screenshot.png", "wb") as f:
f.write(png_bytes)
```

<a id="mobilerun.tools.driver.android.AndroidDriver.get_ui_tree"></a>
<a id="mobilerun.tools.AndroidDriver.get_ui_tree"></a>

#### AndroidDriver.get\_ui\_tree

Expand All @@ -393,7 +393,7 @@ Returns a dictionary containing both the accessibility tree and phone state data

- `Dict[str, Any]` - Raw UI tree data from the device

<a id="mobilerun.tools.driver.android.AndroidDriver.get_date"></a>
<a id="mobilerun.tools.AndroidDriver.get_date"></a>

#### AndroidDriver.get\_date

Expand Down
6 changes: 3 additions & 3 deletions docs/sdk/base-tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: DeviceDriver Base Class

Base class defining the interface for all device drivers.

<a id="mobilerun.tools.driver.base.DeviceDriver"></a>
<a id="mobilerun.tools.DeviceDriver"></a>

## DeviceDriver

Expand Down Expand Up @@ -33,9 +33,9 @@ Every method raises `NotImplementedError` by default. Concrete drivers override

The tools architecture follows a multi-layer pattern:

1. **DeviceDriver** (`tools/driver/base.py`): Base class for raw device I/O. Methods raise `NotImplementedError` by default.
1. **DeviceDriver**: Base class for raw device I/O (provided by `mobilerun-core-cli`). Methods raise `NotImplementedError` by default.
2. **Driver Implementations**: Platform-specific drivers
- `AndroidDriver` (`tools/driver/android.py`): Android devices via ADB + Portal app
- `AndroidDriver`: Android devices via ADB + Portal app (provided by `mobilerun-core-cli`)
- `IOSDriver` (`tools/driver/ios.py`): iOS devices via HTTP REST API to Portal app
- `StealthDriver` (`tools/driver/stealth.py`): Wraps another driver, adds human-like timing jitter
- `RecordingDriver` (`tools/driver/recording.py`): Wraps another driver with trajectory recording
Expand Down
3 changes: 2 additions & 1 deletion mobilerun/agent/action_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
from mobilerun_core_cli.driver.base import DeviceDriver

from mobilerun.agent.droid.state import MobileAgentState
from mobilerun.credential_manager import CredentialManager
from mobilerun.macro.recorder import MacroRecorder
from mobilerun.tools.driver.base import DeviceDriver
from mobilerun.tools.ui.provider import StateProvider
from mobilerun.tools.ui.state import UIState

Expand Down
9 changes: 5 additions & 4 deletions mobilerun/agent/droid/droid_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
from async_adbutils import adb
from llama_index.core.llms.llm import LLM
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
from mobilerun_core_cli.driver.android import AndroidDriver
from mobilerun_core_cli.driver.base import DeviceDisconnectedError
from mobilerun_core_cli.portal import ensure_portal_ready
from opentelemetry import trace
from pydantic import BaseModel
from workflows.events import Event
Expand Down Expand Up @@ -70,15 +73,12 @@
from mobilerun.mcp.adapter import mcp_to_mobilerun_tools
from mobilerun.mcp.client import MCPClientManager
from mobilerun.mcp.config import MCPConfig
from mobilerun.portal import ensure_portal_ready
from mobilerun.telemetry import (
MobileAgentFinalizeEvent,
MobileAgentInitEvent,
capture,
flush,
)
from mobilerun.tools.driver.android import AndroidDriver
from mobilerun.tools.driver.base import DeviceDisconnectedError
from mobilerun.tools.driver.ios import IOSDriver, discover_ios_portal
from mobilerun.tools.driver.recording import RecordingDriver
from mobilerun.tools.driver.stealth import StealthDriver
Expand All @@ -94,7 +94,8 @@
from mobilerun.tools.ui.screenshot_provider import ScreenshotOnlyStateProvider

if TYPE_CHECKING:
from mobilerun.tools.driver.base import DeviceDriver
from mobilerun_core_cli.driver.base import DeviceDriver

from mobilerun.tools.ui.provider import StateProvider

logger = logging.getLogger("mobilerun")
Expand Down
2 changes: 1 addition & 1 deletion mobilerun/agent/fast_agent/fast_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from llama_index.core.base.llms.types import ChatMessage, ImageBlock, TextBlock
from llama_index.core.llms.llm import LLM
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
from mobilerun_core_cli.driver.base import DeviceDisconnectedError
from opentelemetry import trace
from pydantic import BaseModel

Expand Down Expand Up @@ -45,7 +46,6 @@
from mobilerun.agent.utils.tracing_setup import record_langfuse_screenshot
from mobilerun.config_manager.config_manager import AgentConfig, TracingConfig
from mobilerun.config_manager.prompt_loader import PromptLoader
from mobilerun.tools.driver.base import DeviceDisconnectedError
from mobilerun.tools.helpers.images import resize_image_to_max_side_with_grid

if TYPE_CHECKING:
Expand Down
2 changes: 1 addition & 1 deletion mobilerun/agent/manager/manager_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
)
from llama_index.core.llms.llm import LLM
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
from mobilerun_core_cli.driver.base import DeviceDisconnectedError
from opentelemetry import trace
from pydantic import BaseModel

Expand All @@ -47,7 +48,6 @@
ServerAppCardProvider,
)
from mobilerun.config_manager.prompt_loader import PromptLoader
from mobilerun.tools.driver.base import DeviceDisconnectedError
from mobilerun.tools.helpers.images import resize_image_to_max_side_with_grid

if TYPE_CHECKING:
Expand Down
2 changes: 1 addition & 1 deletion mobilerun/agent/manager/stateless_manager_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from llama_index.core.llms.llm import LLM
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
from mobilerun_core_cli.driver.base import DeviceDisconnectedError
from opentelemetry import trace
from pydantic import BaseModel

Expand All @@ -25,7 +26,6 @@
from mobilerun.agent.utils.prompt_resolver import PromptResolver
from mobilerun.agent.utils.tracing_setup import record_langfuse_screenshot
from mobilerun.config_manager.prompt_loader import PromptLoader
from mobilerun.tools.driver.base import DeviceDisconnectedError
from mobilerun.tools.helpers.images import resize_image_to_max_side_with_grid

if TYPE_CHECKING:
Expand Down
3 changes: 1 addition & 2 deletions mobilerun/agent/oneflows/app_starter_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ async def main():
Example of how to use the OpenAppWorkflow.
"""
from llama_index.llms.openai import OpenAI

from mobilerun.tools.driver.android import AndroidDriver
from mobilerun_core_cli.driver.android import AndroidDriver

# Initialize driver with device serial (None for default device)
driver = AndroidDriver(serial=None)
Expand Down
6 changes: 3 additions & 3 deletions mobilerun/cli/device_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

import click
from async_adbutils import adb
from mobilerun_core_cli.driver.android import AndroidDriver
from mobilerun_core_cli.portal import ensure_portal_ready
from rich.console import Console

from mobilerun.config_manager import ConfigLoader
from mobilerun.portal import ensure_portal_ready
from mobilerun.tools.driver.android import AndroidDriver
from mobilerun.tools.driver.ios import (
IOSDriver,
discover_ios_portal,
Expand Down Expand Up @@ -97,7 +97,7 @@ async def _create_driver(
async def _teardown_android(driver):
"""Disable Mobilerun keyboard after direct command execution."""
if isinstance(driver, AndroidDriver) and driver.device:
from mobilerun.portal import PORTAL_PACKAGE_NAME, portal_ime_id
from mobilerun_core_cli.portal import PORTAL_PACKAGE_NAME, portal_ime_id

try:
ime = portal_ime_id(PORTAL_PACKAGE_NAME)
Expand Down
12 changes: 6 additions & 6 deletions mobilerun/cli/doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import httpx
import requests
from async_adbutils import AdbDevice, adb
from rich.console import Console

from mobilerun import __version__
from mobilerun.portal import (
from mobilerun_core_cli.portal import (
GITHUB_API_HOSTS,
PORTAL_PACKAGE_NAME,
REPO,
Expand All @@ -24,7 +21,10 @@
portal_content_uri,
portal_ime_id,
)
from mobilerun.tools.android.portal_client import PortalClient
from mobilerun_core_cli.transport.portal_client import PortalClient
from rich.console import Console

from mobilerun import __version__

console = Console()

Expand Down Expand Up @@ -511,7 +511,7 @@ async def check_portal_state(
device: AdbDevice, use_tcp: bool, debug: bool
) -> tuple[CheckResult, Any]:
"""Fetch full state and verify a11y_tree, phone_state, device_context are present."""
from mobilerun.tools.android.portal_client import PortalClient
from mobilerun_core_cli.transport.portal_client import PortalClient

try:
portal = PortalClient(device, prefer_tcp=use_tcp)
Expand Down
24 changes: 12 additions & 12 deletions mobilerun/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@

import click
from async_adbutils import adb
from mobilerun_core_cli.portal import (
DOWNLOAD_BASE,
PORTAL_PACKAGE_NAME,
download_portal_apk,
download_versioned_portal_apk,
enable_portal_accessibility,
ping_portal,
ping_portal_content,
ping_portal_tcp,
setup_portal,
)
from rich.console import Console
from rich.panel import Panel
from rich.text import Text
Expand Down Expand Up @@ -47,17 +58,6 @@
)
from mobilerun.log_handlers import CLILogHandler, configure_logging
from mobilerun.macro.cli import macro_cli
from mobilerun.portal import (
DOWNLOAD_BASE,
PORTAL_PACKAGE_NAME,
download_portal_apk,
download_versioned_portal_apk,
enable_portal_accessibility,
ping_portal,
ping_portal_content,
ping_portal_tcp,
setup_portal,
)
from mobilerun.telemetry import print_telemetry_message
from mobilerun.tools.driver.ios import discover_ios_portal, validate_ios_portal_url
from mobilerun.tools.driver.visual_remote import VISUAL_REMOTE_CONNECTION
Expand Down Expand Up @@ -329,7 +329,7 @@ async def _cleanup_android_keyboard(config: MobileConfig) -> None:
try:
device_obj = await adb.device(config.device.serial)
if device_obj:
from mobilerun.portal import PORTAL_PACKAGE_NAME, portal_ime_id
from mobilerun_core_cli.portal import PORTAL_PACKAGE_NAME, portal_ime_id

ime = portal_ime_id(PORTAL_PACKAGE_NAME)
await device_obj.shell(f"ime disable {ime}")
Expand Down
6 changes: 2 additions & 4 deletions mobilerun/cli/tui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,7 @@ def on_device_picker_cancelled(self, message: DevicePicker.Cancelled) -> None:
async def _verify_portal(self, serial: str) -> None:
"""Check portal connectivity. Raises on failure."""
from async_adbutils import adb

from mobilerun.tools.android.portal_client import PortalClient
from mobilerun_core_cli.transport.portal_client import PortalClient

device_obj = await adb.device(serial)
portal = PortalClient(device_obj, prefer_tcp=self.settings.use_tcp)
Expand Down Expand Up @@ -630,8 +629,7 @@ async def _run_device_setup(self, serial: str) -> None:

import requests
from async_adbutils import adb

from mobilerun.portal import (
from mobilerun_core_cli.portal import (
_resolve_latest_portal_apk_asset,
_resolve_versioned_portal_apk_asset,
enable_portal_accessibility,
Expand Down
Loading
Loading