{"id":43374218,"url":"https://github.com/droidrun/droidrun-portal","last_synced_at":"2026-02-02T06:18:45.793Z","repository":{"id":288309160,"uuid":"965314035","full_name":"droidrun/droidrun-portal","owner":"droidrun","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-29T11:08:57.000Z","size":2446,"stargazers_count":276,"open_issues_count":12,"forks_count":89,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-01-30T01:51:53.567Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://droidrun.ai","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/droidrun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-12T22:05:45.000Z","updated_at":"2026-01-29T11:09:01.000Z","dependencies_parsed_at":"2026-01-08T09:07:37.357Z","dependency_job_id":null,"html_url":"https://github.com/droidrun/droidrun-portal","commit_stats":null,"previous_names":["droidrun/droidrun-portal"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/droidrun/droidrun-portal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/droidrun%2Fdroidrun-portal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/droidrun%2Fdroidrun-portal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/droidrun%2Fdroidrun-portal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/droidrun%2Fdroidrun-portal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/droidrun","download_url":"https://codeload.github.com/droidrun/droidrun-portal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/droidrun%2Fdroidrun-portal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29006910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T04:25:24.522Z","status":"ssl_error","status_checked_at":"2026-02-02T04:24:51.069Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-02T06:18:41.397Z","updated_at":"2026-02-02T06:18:45.785Z","avatar_url":"https://github.com/droidrun.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./static/droidrun-dark.png\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./static/droidrun.png\"\u003e\n  \u003cimg src=\"./static/droidrun.png\"  width=\"full\"\u003e\n\u003c/picture\u003e\n\n[![GitHub stars](https://img.shields.io/github/stars/droidrun/droidrun-portal?style=social)](https://github.com/droidrun/droidrun-portal/stargazers)\n[![Discord](https://img.shields.io/discord/1360219330318696488?color=7289DA\u0026label=Discord\u0026logo=discord\u0026logoColor=white)](https://discord.gg/ZZbKEZZkwK)\n[![Documentation](https://img.shields.io/badge/Documentation-📕-blue)](https://docs.droidrun.ai)\n[![Twitter Follow](https://img.shields.io/twitter/follow/droid_run?style=social)](https://x.com/droid_run)\n\n\u003ca href=\"https://github.com/droidrun/droidrun-portal/releases\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/Kunzisoft/Github-badge/main/get-it-on-github.png\" alt=\"Get it on GitHub\" style=\"width:200px;height:auto;\"\u003e\n\u003c/a\u003e\n\n## 👁️ Overview\nDroidrun Portal is an Android accessibility service that provides real-time visual feedback and data collection for UI elements on the screen. It creates an interactive overlay that highlights clickable, checkable, editable, scrollable, and focusable elements, making it an invaluable tool for UI testing, automation development, and accessibility assessment.\n\n## ✨ Features\n\n- Interactive overlay that highlights clickable, checkable, editable, scrollable, and focusable elements\n- Local control APIs (HTTP socket server, WebSocket JSON-RPC, and ContentProvider)\n- Reverse WebSocket connection for cloud control\n- WebRTC screen streaming with auto-accept support\n- APK install from URLs (including split APKs) with optional auto-accept\n- Notification event streaming with per-event toggles\n\n## 🚀 Usage\n\n### ⚙️ Setup\n1. Install the app on your Android device\n2. Enable the accessibility service in Android Settings → Accessibility → Droidrun Portal\n3. Grant overlay permission when prompted\n4. (Optional) Open **Settings** in the app to enable local servers or reverse connection\n\n### 🔐 Auth Token (Local APIs)\n\nDroidrun Portal generates a local auth token for HTTP and WebSocket access.\n\n- In the app: copy the token from the main screen\n- Via ADB:\n  ```bash\n  adb shell content query --uri content://com.droidrun.portal/auth_token\n  ```\n\n### 🧩 Local APIs\n\nDroidrun Portal exposes three local interfaces:\n\n- HTTP socket server (default port 8080)\n- WebSocket server (default port 8081)\n- ContentProvider (ADB commands)\n\nSee [Local API](docs/local-api.md) for full details and examples.\n\n### 📡 WebSocket Events\n\nDroidrun Portal streams notification events over WebSocket when enabled in Settings.\n\nSee the [WebSocket Events documentation](docs/websocket-events.md) for setup, permissions, and event formats.\n\n### 🌐 Reverse Connection (Cloud)\n\nEnable reverse connection to let the device initiate an outbound WebSocket connection to a host (used by Mobilerun Cloud).\n\nSee [Reverse Connection](docs/reverse-connection.md) for configuration details and the streaming protocol.\n\n### 💻 ADB Commands (ContentProvider)\n\nAll commands use the ContentProvider authority `content://com.droidrun.portal/`.\n\n#### Query Commands (Reading Data)\n\n```bash\n# Test connection (ping)\nadb shell content query --uri content://com.droidrun.portal/ping\n\n# Get app version\nadb shell content query --uri content://com.droidrun.portal/version\n\n# Get accessibility tree as JSON (visible elements with overlay indices)\nadb shell content query --uri content://com.droidrun.portal/a11y_tree\n\n# Get full accessibility tree with ALL properties (complete node info)\nadb shell content query --uri content://com.droidrun.portal/a11y_tree_full\n\n# Get full tree without filtering small elements (\u003c 1% visibility)\nadb shell content query --uri 'content://com.droidrun.portal/a11y_tree_full?filter=false'\n\n# Get phone state as JSON (current app, focused element, keyboard visibility)\nadb shell content query --uri content://com.droidrun.portal/phone_state\n\n# Get combined state (accessibility tree + phone state)\nadb shell content query --uri content://com.droidrun.portal/state\n\n# Get full combined state (full tree + phone state + device context)\nadb shell content query --uri content://com.droidrun.portal/state_full\n\n# Get full state without filtering\nadb shell content query --uri 'content://com.droidrun.portal/state_full?filter=false'\n\n# Get list of installed launchable apps\nadb shell content query --uri content://com.droidrun.portal/packages\n\n# Get local auth token for HTTP/WS access\nadb shell content query --uri content://com.droidrun.portal/auth_token\n```\n\n#### Insert Commands (Actions \u0026 Configuration)\n\n```bash\n# Keyboard text input (base64 encoded, clears field first by default)\nadb shell content insert --uri content://com.droidrun.portal/keyboard/input --bind base64_text:s:\"SGVsbG8gV29ybGQ=\"\n\n# Keyboard text input without clearing the field first\nadb shell content insert --uri content://com.droidrun.portal/keyboard/input --bind base64_text:s:\"SGVsbG8=\" --bind clear:b:false\n\n# Clear text in focused input field\nadb shell content insert --uri content://com.droidrun.portal/keyboard/clear\n\n# Send key event via keyboard (e.g., Enter key = 66, Backspace = 67)\nadb shell content insert --uri content://com.droidrun.portal/keyboard/key --bind key_code:i:66\n\n# Set overlay vertical offset (in pixels)\nadb shell content insert --uri content://com.droidrun.portal/overlay_offset --bind offset:i:100\n\n# Toggle overlay visibility (show/hide)\nadb shell content insert --uri content://com.droidrun.portal/overlay_visible --bind visible:b:true\nadb shell content insert --uri content://com.droidrun.portal/overlay_visible --bind visible:b:false\n\n# Configure REST API socket server port (default: 8080)\nadb shell content insert --uri content://com.droidrun.portal/socket_port --bind port:i:8090\n\n# Enable/disable local WebSocket server (default port: 8081)\nadb shell content insert --uri content://com.droidrun.portal/toggle_websocket_server --bind enabled:b:true --bind port:i:8081\n\n# Configure reverse connection (host URL + optional token/service key)\nadb shell content insert --uri content://com.droidrun.portal/configure_reverse_connection --bind url:s:\"wss://api.mobilerun.ai/v1/providers/personal/join\" --bind token:s:\"YOUR_TOKEN\" --bind enabled:b:true\nadb shell content insert --uri content://com.droidrun.portal/configure_reverse_connection --bind service_key:s:\"YOUR_KEY\"\n\n# Toggle production mode UI\nadb shell content insert --uri content://com.droidrun.portal/toggle_production_mode --bind enabled:b:true\n```\n\n#### Common Key Codes\n\n| Key | Code | Key | Code |\n|-----|------|-----|------|\n| Enter | 66 | Backspace | 67 |\n| Tab | 61 | Escape | 111 |\n| Home | 3 | Back | 4 |\n| Up | 19 | Down | 20 |\n| Left | 21 | Right | 22 |\n\n### 📤 Data Output\nElement data is returned in JSON format through the ContentProvider queries. The response includes a status field and the requested data. All responses follow this structure:\n\n```json\n{\n  \"status\": \"success\",\n  \"result\": \"...\"\n}\n```\n\nFor error responses:\n```json\n{\n  \"status\": \"error\", \n  \"error\": \"Error message\"\n}\n```\n\n## 🔧 Technical Details\n- Minimum Android API level: 30 (Android 11.0)\n- Uses Android Accessibility Service API\n- Implements custom drawing overlay using Window Manager\n- Supports multi-window environments\n- Built with Kotlin\n\n\n## 🔄 Continuous Integration\n\nThis project uses GitHub Actions for automated building and releasing.\n\n### 📦 Automated Builds\n\nEvery push to the main branch or pull request will trigger the build workflow that:\n- Builds the Android app\n- Creates the APK\n- Uploads the APK as an artifact in the GitHub Actions run\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdroidrun%2Fdroidrun-portal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdroidrun%2Fdroidrun-portal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdroidrun%2Fdroidrun-portal/lists"}