Usage guide

Every feature, three ways — click it in the GUI, run it on the CLI, or call it from Python. Target a device with -s SERIAL (or an ADBConfig); add --adb-host HOST for a device on another machine.

Target a device

Everything operates on one device — local USB, a network device, or one on another machine's adb server.

GUI
  1. Click Connect ▾ → Connect to a device…
  2. Under How is it connected? pick USB, Network (IP and port) or Remote (a device on another PC's adb server).
  3. Hit Connect — a device tab opens with Terminal, Logcat, Files, Device Control, Apps, Phone and Webcam.

Attached devices also appear under Connected in the left sidebar — double-click any to open it. For Wi-Fi use Connect ▾ → Discover Wi-Fi devices or Pair device (Android 11+), or switch a USB device with More ▾ → Go wireless (USB → Wi-Fi).

CLI
turboadb devices
turboadb -s 10BE330KG9000AF info
turboadb -s 10BE330KG9000AF wireless     # USB -> Wi-Fi adb
turboadb discover                         # find wireless-debugging devices
turboadb --adb-host lab-pc-01 -s DEVICE info
Python
from turboadb import ADBHandler, ADBConfig
dev = ADBHandler(ADBConfig(serial="10BE330KG9000AF"))
# remote: ADBConfig(adb_server_host="lab-pc-01", serial="DEVICE")
dev.connect()

Terminal

A real terminal with history, tab-completion, and a Stop button that sends a real Ctrl+C to a runaway command like logcat — plus PowerShell and Command Prompt on this PC.

GUI
  1. Open a device → Terminal tab → type. The boxed banner at the top shows the connection, device type, Android version, CPU and serial. The Android shell runs on a device terminal, so ping and logcat | grep show their output as it comes and programs that ask for input (read, su) work. Full-screen programs (top, vi, less) redraw in place and get every key. Colour is kept for what matters: the words that say what happened (a red Permission denied or not found, an amber Warning, a green Success) and logcat's warning and error lines; the prompt is one quiet colour and everything else stays plain.
  2. Right-click for Copy / Paste / Send key / Save full output to file…; Stop (Ctrl+C) stops whatever is running and keeps the shell (ping prints its summary); a command that ignores it is ended by reopening the shell in the same folder. A− / A+ resize every terminal together (12 pt by default).
  3. Click PowerShell or CMD in the switcher for a Windows shell with TurboADB's adb first on PATH and ANDROID_SERIAL set — Python, Git and where work like in a normal console, and Stop works like Ctrl+C in a console window: the command stops and the shell keeps its folder and variables (a program that answers Ctrl+C, such as a python prompt, keeps running; a shell still waiting for an answer three seconds later gets a fresh shell in the same folder). Inside an adb shell typed there, Stop stops only the device command and keeps you in adb shell; if the command ignores it, Stop again reopens adb shell in the same folder.
CLI
turboadb -s SERIAL shell -- getprop ro.build.version.release
Python
import time
r = dev.shell("getprop ro.product.model")
print(r.stdout, r.ok)
sess = dev.open_shell(); sess.send("ls /sdcard\n")
time.sleep(0.5); print(sess.read())   # read() never waits: it returns what has arrived

Logcat

Filter by level / tag / app / live regex, highlight keywords, pause, and save the complete log — nothing is dropped under a flood.

GUI
  1. Open the Logcat tab, pick the level and how much history to include (Live from now, Last 1,000 + live, …) and optionally Tag(s) (comma-separated) or an App (package name or PID, Android 7+).
  2. Press Start (or the Crashes preset). Type a regex in Filter to hide non-matching lines (it ignores case unless Aa is on, and searches the whole capture), or in Highlight (e.g. error|anr|crash) to mark matches in-line without hiding the rest.
  3. Save… writes the complete log to a .log file.
CLI
turboadb -s SERIAL logcat --tag ActivityManager --match "ANR|FATAL" --save crash.log
Python
dev.logcat(tag="ActivityManager", match="ANR", on_line=print, save_to="crash.log")
for line in dev.iter_lines(["logcat", "-v", "threadtime"]):
    ...

Files (push / pull)

GUI

Files tab → This PC and Device side by side → select files and press Push or Pull, or drag and drop (also from Explorer). New folder, New file, Open, Edit (F4), Copy / Paste, Rename (F2) and Delete work in both panes.

Double-click (or Enter) opens a file in its app on this PC: pictures in Photos, videos in Media Player, text in Notepad, or any app you pick with Open with…. A device file opens as a copy, and each time you save it there it goes back to the device (TurboADB asks first if the device file changed meanwhile). Programs are never started; scripts and files no app opens go to the built-in editor, which asks the same before it saves over a device file that changed since you opened it.

Drag beside the names to select a block, Ctrl+A for all, Enter to open, Backspace to go up. Delete sends local files to the Recycle Bin, Shift+Delete deletes for good. A PC file or folder whose name ends in a dot or a space (made by WSL, Git Bash or a Linux drive) is left alone, with a message saying why. If the device refuses a change, TurboADB offers adb root, disable-verity and remount, then tries again.

CLI
turboadb -s SERIAL push app.apk /data/local/tmp/
turboadb -s SERIAL pull /sdcard/Download/log.txt .
Python
dev.push("app.apk", "/data/local/tmp/")
dev.pull("/sdcard/Download/log.txt", "log.txt")

Apps

List, install (single or split APKs), uninstall, clear data, start / stop.

GUI

Apps tab → Install APK(s)…, or filter the list (Third-party only) and pick a package for Start, Stop, Clear data or Uninstall.

CLI
turboadb -s SERIAL packages --third-party
turboadb -s SERIAL install app.apk --grant
turboadb -s SERIAL uninstall com.example.app
Python
dev.list_packages(third_party=True)
dev.install("app.apk", grant_perms=True)
dev.install_multiple(["base.apk", "split_config.apk"])
dev.uninstall("com.example.app")

Device controls

Keys, media, connectivity, screen, app launchers, and an on-screen keyboard — the Device controls panel, each also a command and a call.

GUI

Device Control tab → the Device controls panel beside the screen: Navigation, Media & volume, Quick settings (Wi-Fi, Bluetooth, Mobile data, Airplane mode, Hotspot), Screen & power, Apps & web and Keyboard.

CLI
turboadb -s SERIAL key home
turboadb -s SERIAL media play-pause
turboadb -s SERIAL wifi on        # bluetooth | airplane | hotspot
turboadb -s SERIAL screen off
turboadb -s SERIAL open https://maps.google.com
turboadb -s SERIAL text "hello world"
Python
dev.keyevent("home"); dev.media("play-pause")
dev.set_wifi(True); dev.set_hotspot(True); dev.screen_off()
dev.open_url("https://maps.google.com"); dev.input_text("hello world")

Mirroring (scrcpy)

In a window or embedded, with a compatibility mode for IVI units and remote-tunnel handling. Type on the screen, record while it is live, manage every display, or mirror the device's own camera.

GUI
  1. Open the device's Device Control tab (or use Screen ▾ at the right end of the section tabs).
  2. Pick a display, then Start screen (inside the tab) or Separate window. Click the screen to type on it with your PC keyboard.
  3. Options holds audio, Compatibility mode (IVI / automotive) for stubborn head units, the keyboard mode, Device camera (Back / Front), Manage displays… and All displays.
  4. Record… records without restarting the live view; Maximize view and Hide controls give the screen more room (Show controls works while maximized too). The controls sit beside the screen or below it, whichever shows the screen larger.
  5. On cars (and any device with several displays) the IVI Displays tab shows every display side by side, each with its own Start / Stop and Back, Home, Recents, volume, power and screenshot buttons. Every display starts stopped (opening the tab or a rescan never starts one): start the ones you need, or Start all to start them one after another. Maximize shows a single display (Esc restores); Start all, Stop all and Rescan are at the top.
  6. If scrcpy can't run on a build, Settings → scrcpy → Screen renderer → ADB screencap shows the screen through adb screencap — slower, but touch, drag, scroll and typing still work.

The display picker lists every display with its name and size as soon as the device connects — TurboADB asks Android over adb, so connecting never starts scrcpy on its own.

CLI
turboadb -s SERIAL scrcpy --max-size 1280 --bit-rate 8M
turboadb -s SERIAL scrcpy --video-source camera --camera-facing front
Python
from turboadb import ScrcpyOptions
sess = dev.mirror(ScrcpyOptions(max_size=1280, bit_rate="8M"))
sess.wait()
# device camera instead of the screen:
dev.mirror(ScrcpyOptions(video_source="camera", camera_facing="front"))

Screenshots & recording

The CLI and Python recording use device-side screenrecord, so they work over RDP without a video tunnel.

GUI

Screenshot at the right end of the section tabs; Record… in the Device Control screen toolbar. With the screen live, a second, windowless recorder runs beside it and saves a playable MP4. Closing TurboADB while a recording runs or is still being saved waits for it: a dialog names the file, and Close without saving is the way out.

CLI
turboadb -s SERIAL screenshot shot.png
turboadb -s SERIAL record clip.mp4 --time-limit 20 --size 1280x720
Python
dev.screenshot("shot.png")
dev.screen_record("clip.mp4", time_limit=20, size="1280x720")

Webcam (host camera)

Different from the device camera above: this views a host webcam — a USB / laptop camera on the machine running TurboADB. Point one at the physical head unit or bench and watch it beside the mirror. It captures locally, so it also works when TurboADB runs inside an RDP session (it sees that session's redirected camera).

GUI · Local
  1. Choose Tools ▾ → Open host webcam (or View → Open webcam (host camera)) — it opens as a standalone tab, no device needed. Every device also has its own Webcam tab. Source = Local — this PC.
  2. Click Scan cameras (the first time, ffmpeg is fetched once, ~160 MB → ~/.turboadb/ffmpeg), pick a camera, resolution and frame rate.
  3. Press Start camera. Then Snapshot, Record (clean H.264 MP4), Pause, Rotate, Flip, and View: Fit · Fill · Stretch.

No camera listed over RDP? Enable camera redirection in the RDP client (Local Resources → More… → Cameras), turn on Windows camera privacy, and close any app already using it.

GUI · Remote (no SSH)
  1. Set Source = Remote — Windows PC and enter the RDP host, User, Domain and Password.
  2. Scan cameras, then Start camera — TurboADB uses the same WinRM/NTLM path as deploy-serve to launch ffmpeg on the remote and stream its camera back over a direct TCP socket. Each stream uses a port of its own (28100–28115): open that range in a firewall between the PCs to view more than one.

The target needs WinRM on (Enable-PSRemoting -Force) and the account a local admin. ffmpeg is downloaded onto the remote automatically on first use (or drop ffmpeg.exe in %USERPROFILE%\.turboadb\ffmpeg\). The host / user / domain are remembered and the password is kept in the Windows Credential vault, never in a file. A physical USB camera works headlessly; a camera redirected into an RDP session is only visible inside it. Record encodes on this PC, and offers the one-time ffmpeg download when this PC has none.

Note

The webcam is a desktop feature (not an adb device op, so there's no CLI / Python call). Bring your own ffmpeg via Settings → ffmpeg path for offline use.

Telephony

GUI
  1. Open the device's Phone tab. The pill shows Idle, Ringing or In call, and Checking… while the device does not answer (it is rebooting or unplugged): the page loads again once the device is back.
  2. Type a number or use the keypad (hold 0 for +), then Call, End or Answer. Open in dialler (or Enter) only opens the device dialler pre-filled. While the pill shows Idle, End sends nothing.
  3. Switch between Recent calls and Messages. Call back fills the dialler; Compose in Messages opens a draft on the device, where you press Send.

On a head unit without a phone the tab checks what the device has and says so calmly: no telephony, no call history, and — when there's no standard phone app — an Open … button for the device's own phone app instead of a dialler that can't work.

CLI
turboadb -s SERIAL call 1800123456
turboadb -s SERIAL call-log --limit 20
turboadb -s SERIAL send-sms 1800123456 "on my way"
Python
dev.call("1800123456"); dev.end_call()
for c in dev.call_log(20): print(c)
dev.send_sms("1800123456", "on my way")

Root & mount

For rooted / engineering builds.

GUI

More ▾ → Root and mount at the right end of the section tabs.

CLI
turboadb -s SERIAL root         # unroot to undo
turboadb -s SERIAL mount-rw
turboadb -s SERIAL disable-verity
Python
dev.root(); dev.remount(); dev.mount_rw(); dev.disable_verity()

Remote devices

Drive a device plugged into another machine over its adb server — the host just has to be sharing (see Serve).

GUI

Connect ▾ → Connect to a device… → Remote; enter that PC's host, then Scan devices there and pick the device.

CLI
turboadb devices --adb-host lab-pc-01
turboadb --adb-host lab-pc-01 -s DEVICE shell -- pm list packages
Python
dev = ADBHandler(ADBConfig(adb_server_host="lab-pc-01", serial="DEVICE"))
dev.connect()

Share devices (serve)

Turn the machine a device is plugged into a host others can reach.

GUI

ADB server ▾ → Share THIS PC's devices… (Start once or Start + run at login; opening the firewall needs Administrator, and sharing ends on a warning when the firewall may keep other machines out). To undo it, ADB server ▾ → Stop sharing & remove auto-start — stops sharing and removes both the login launcher and the SYSTEM startup task. Removing that task needs Administrator too: TurboADB says so when it is still installed.

The shared adb server has no password: anyone who can reach its port can control the devices. The firewall rules therefore apply on Domain and Private networks only; on a network Windows calls Public nobody can connect until you make it Private. Stopping sharing deletes the rules again.

CLI
turboadb serve --startup-task    # shared server + firewall, headless across reboots
turboadb serve --uninstall-startup   # stop auto-start again
Python
from turboadb.devices import (start_shared_server, install_serve_task,
                              stop_shared_server, uninstall_serve_task)
start_shared_server(); install_serve_task()
# undo (uninstall_serve_task raises RuntimeError when the task could not be removed):
uninstall_serve_task(); stop_shared_server()

Deploy serve over WinRM

Push serve onto remote Windows hosts from your machine — one host or a fleet. Each target needs WinRM on and admin rights.

GUI

ADB server ▾ → Deploy to remote machine(s) (RDP / WinRM)… → enter host(s) + admin credentials → Test connection → Deploy.

CLI
turboadb deploy-serve lab-pc-01 lab-pc-02 -u "DOMAIN\user"
turboadb deploy-serve lab-pc-01 -u "DOMAIN\user" --test
Python
from turboadb.remote_deploy import deploy_serve
deploy_serve(["lab-pc-01", "lab-pc-02"], "DOMAIN\\user", "password", on_status=print)

GUI extras

Small conveniences that make long sessions nicer.

GUI
  • Themes — Graphite / Porcelain by default, plus Black / White, Slate / Mist, Night / Paper and Mocha / Latte, all soft on the eyes. The top-bar sun or moon switches between your last dark and last light theme; its arrow, the Themes menu and Settings → Themes pick any theme directly.
  • Split view — More ▾ → Split view shows Terminal, Device Control, Files and Logcat side by side, stacked or in a grid.
  • Maximize view and Hide controls in Device Control give the screen the whole window; ‹ or Ctrl+B hides the device list.
  • Notifications — a small toast for every action and a red popup with a sound and Copy for errors. The log panel icon opens the filterable log (Normal, Verbose, Warnings + Errors, Errors only).
  • Settings — Appearance, Tools (adb / scrcpy / ffmpeg paths), scrcpy video and audio, Logcat, Themes and Startup.
  • Menu bar extras — export / import saved targets (File) and Run a command on ALL devices… (Device).

Keep things up to date

GUI

Tools ▾ → Check for updates… updates TurboADB from PyPI, refreshes adb/scrcpy, and restarts. The standalone Windows app and a source checkout, which pip cannot update, are told when a newer version is out and how to get it. Tools ▾ → Download and reinstall ADB and scrcpy… refreshes only the tools.

CLI
turboadb self-update      # TurboADB + adb/scrcpy
turboadb upgrade-tools    # only adb/scrcpy
turboadb doctor           # what's installed / missing
Python
from turboadb import upgrade_tools
upgrade_tools()