Tactile
Verified for real — 145 frames in 6 s

A real Android in your browser, by the minute

You open a session and the phone shows up in the tab: you touch, you type, you install your APK. On close, the device is reset — the previous customer's APK is gone.

No credit card to start. Secure payment through Stripe when you change plan.

Real capture of the Redmi Note 13 screen during a Tactile session: the lock screen, as relayed into the browser
  • Touchclick = tap
  • Dragdrag = swipe
  • Textkeyboard, Ctrl+V
  • System buttonsHome, Back, Recents
  • Toolbarrotate, volume, power
  • Sessioncapture, stats, close

Real capture: the fleet Redmi screen, relayed into the viewer.

Verified for real

145 frames relayed in 6 seconds, decoded at ~30 frames per second

This is not a lab estimate: it is a real session, on a real device, read in the browser. The H.264 stream crosses Tactile byte for byte — the relay does not rewrite it, it copies it.

  • 145frames relayed
  • 6 sof measured session
  • 219 koover the channel
  • ~30 i/sframes per second
  • 460 × 1024session.ready
  • avc1.640020codec read from the SPS
The Tactile viewer during the verification session: the device screen, the toolbar and the text field
The viewer during the session: the screen on top, the toolbar and the text field below. A capture of the product, not a mock-up.

What was measured, and what was not

  • One session, one device: Redmi Note 13, Android 13. The rest of the fleet has not been measured end to end.
  • A screenshot requires a target: the platform has no “capture the current screen” job, and Tactile answers 400 unsupported_target.
  • No adb shell: only the toolbar actions, all reversible.
  • The stream goes through vpsmain: ~4 Mbit/s per session, 40 Mbit/s at ten sessions. VPS bandwidth is the limiting factor.
Questions

Frequently asked questions

Do I get an `adb shell`?

No, not in v1: only the toolbar actions (touch, keyboard, system buttons, rotation, volume, APK upload, screenshot, opening a URL). The shell will come later, as an allow-list of commands.

Can I capture the current screen?

No: a platform `capture` requires a target (`package` or `url`); there is no "capture the current screen" job. Without a target, Tactile answers `400 unsupported_target` instead of pretending. The viewer itself snapshots the view displayed in the browser, without a job.

Is logcat a continuous stream?

No: `GET /api/v1/sessions/:id/logcat` requires a `package` and relaunches the targeted app with a filter. No control action gives access to the shell — on purpose.

Can I book a time slot in advance?

Not in phase 1: time-slot bookings, the back office and the clipboard are out of scope. The simultaneous session ceiling (`max_parallel`) is stored on the key but not enforced.

Are the devices signed in to a Google account?

No: rented devices are connected to no personal Google account — a service account per device, or none. A session therefore leaves nothing behind.

What it does

Concretely

Real devices, not emulators

The fleet is in France, with its real manufacturers, real networks and real fonts. An emulator renders your page the same way for everyone; a Redmi running MIUI does not.

The session channel, verified for real

Tactile is the only product in the family measured end to end on a real device: 145 frames / 219 kB in 6 s (~30 fps), `session.ready` 460 × 1024, `avc1.640020` rebuilt from the SPS. The H.264 stream is relayed byte for byte.

An opaque token, never the API key

The browser only ever sees an opaque session token; the customer lease is replaced by the lease of their session. That is what stops one customer from watching or driving another one's device.

Every session starts clean

On close, a `reset` job uninstalls the customer APK, clears downloads and signs out the accounts added during the session. The next customer finds no trace of the previous one.

No surprise at the end of a session

Five minutes idle: warning, then close. Browser killed abruptly: the lease is released in under 60 s (a 10 s grace period plus a sweep), and minutes are only charged once.

Billed by the minute

Billing follows the open → closed state transition: a double call (the `DELETE` route and then the sweeper) does not charge twice. A credit ceiling stops the session before the surprise.

The control bar

What your mouse sends to the device

Every browser gesture becomes a precise action on the device. Nothing goes through a shell: these are control events, so nothing can stay broken after your session.

The Tactile viewer toolbar, real capture: Home, Back, Recents, Rotate, Vol +, Vol −, Power, Wake, Capture, Stats, Close, then the text field
The viewer toolbar, as it is: system buttons, session commands, and the “Text to type” field.
In the browser On the device
Click or tap on the screen touch down then up, at video coordinates; scrcpy scales them back to the real screen.
Drag touch down + move (at most one every 30 ms) + up: the gesture leaves continuously, not as a jump.
Wheel scroll, clamped to ±20 units per event.
Typing letters leave as text; Enter (66), Back (67), Delete (112), arrows, Tab and Escape → Back leave as key.
Ctrl+V the clipboard, truncated to 500 characters.
“Text to type” field + Send up to 2,000 characters at once, without going through the virtual keyboard.
Toolbar Home, Back, Recents, Rotate, Volume +/−, Power, Wake: system key codes, not shell.
Capture and Stats browser side: a snapshot of the displayed view and the counters (decoded frames, decoder queue, WebSocket, billing).
Close releases the device, triggers the reset and charges the minutes consumed — once only.
In all honesty

What we do not do

A product that hides its limits wastes everybody's time. Here are ours, today.

  • No raw `adb shell` for the customer: only the toolbar actions (the shell will come as an allow-list, later).
  • Screenshots require a target: "capture the current screen" does not exist on the platform side, and Tactile answers `400 unsupported_target`.
  • Logcat is not a continuous stream: it requires a `package` and relaunches the targeted app.
  • The simultaneous session ceiling (`max_parallel`) is stored on the key but not enforced.
  • No time-slot bookings, no back office, no clipboard, no video recording: no matching control action exists on the platform side.
  • Verified for real on a single device (Redmi Note 13, Android 13): the rest of the fleet has not been measured end to end.
  • Stripe is not wired up: the billing page says so, the payment route answers 503, and credits are created by hand.
  • The video stream goes through vpsmain: at ~4 Mbit/s per session, 10 sessions make 40 Mbit/s. The VPS bandwidth is the limiting factor.
  • The platform SDK does not expose leases yet: Tactile carries `createLease` / `heartbeatLease` / `releaseLease` itself in the meantime, and reports it.

Open a session

Create an account, take a key, open a device from the fleet. The trial gives 60 minutes, no credit card.