Skip to content

adb-input

Fresh

Source: BIBLE.md (adb-input.mjs section), bible/understand-everything.md (How ADB input works)

core/adb-input.mjs provides humanized touch, keyboard, and scroll via ADB shell commands. Same Bezier math as human-mouse.mjs, but delivered through adb shell input to Android devices and Waydroid containers.

Why it works

ADB input is already isTrusted: true. Android treats it as real touch events. No additional evasion needed at the OS layer.

flowchart LR
  N[Node.js] --> ADB[spawn adb shell]
  ADB --> AND[Android input subsystem]
  AND --> APP[App: isTrusted=true]

Key functions

FunctionWhat it does
adbHumanTap(serial, x, y)Touch-down with natural press duration, ±12 px spread
adbDoubleTap(serial, x, y)Two taps with 50-120 ms gap
adbLongPress(serial, x, y, durationMs)Hold via swipe-to-self
adbSwipeBezier(serial, x1, y1, x2, y2)Bezier curve swipe via chained short segments
adbScroll(serial, opts)Scroll with ease-in-out, optional reading micro-pauses
adbScrollFeed(serial, count)Multi-swipe feed browsing with re-reading behavior
adbType(serial, text)Character-by-character with 3 speed profiles
adbKeyEvent(serial, keycode)BACK, HOME, ENTER, etc.
adbScreenshot(serial)screencap -p to base64 PNG
adbScreenSize(serial)wm size to {width, height}
adbConnect(serial)TCP/IP or USB connect
adbListDevices()All connected devices
adbDeviceInfo(serial)OS, build, model

KEYCODE constants

BACK, HOME, ENTER, TAB, DELETE, MENU, SEARCH,
VOLUME_UP, VOLUME_DOWN, POWER, APP_SWITCH

Bezier swipes

The same cubic interpolation as desktop mouse, but delivered as chained short ADB swipe segments. Each segment is ~20 to 40 ms. The cumulative path looks like a real finger drag.

flowchart LR
  S[Start touch x1,y1] --> P1[Bezier point 1]
  P1 --> P2[Bezier point 2]
  P2 --> P3[Bezier point 3]
  P3 --> E[End touch x2,y2]

Speed profiles for typing

Same fast/normal/slow as desktop:

ProfileAvg ms/char
fast60-100
normal100-180
slow200-350

Constraints

ADB latency per character

adbType spawns one adb shell input text per character for natural variance. For long text, this adds up: about 100-180 ms per character at normal speed.

Batch input is available via adb shell input text 'whole string' but loses per-character humanization.

Text encoding

adb shell input text only reliably handles Latin-1 characters. CJK or emoji may not survive the encoding.

Alternative for special chars: adb shell am broadcast with a clipboard helper app.

Always ghost mode

ADB backend always forces ghost mode. No CDP on mobile. The router sets:

  • mode = ghost
  • backend = adb
  • vision = true

ADB is the only I/O path on mobile.

Multi-device support

Unlimited concurrent mobile sessions. Each session is bound to a unique serial. No window focus problem like desktop.

Mobile API surface

13 mobile routes are built on top of adb-input:

MethodRoute
GET/mobile/devices
POST/mobile/connect
GET/mobile
GET/mobile/:id
POST/mobile/:id/tap
POST/mobile/:id/type
POST/mobile/:id/scroll
POST/mobile/:id/scroll-feed
POST/mobile/:id/keyevent
POST/mobile/:id/screenshot
POST/mobile/:id/vision-find
POST/mobile/:id/vision-verify
POST/mobile/:id/close

Lineage

V1 plugins adb-bridge and mobile-behavior were consolidated and upgraded into core/adb-input.mjs. Same concepts, better humanization, Bezier curves instead of linear swipes.