Input boundary
The Compose control surface produces semantic requests—motion, button state, clicks, and horizontal scroll—rather than raw report bytes. A foreground service validates those requests and passes them to the shared HID session.
| Transport | Classic HID Device with BLE HOGP fallback |
|---|---|
| Report range | Each relative motion component is segmented into signed 8-bit HID deltas |
| Queue model | Bounded ingress, semantic, and pending-command capacities |
| Persistent state | Verified hosts and local control preferences |
Motion coalescing without reordering
Pointer movement is coalesced while it remains adjacent. A button, click, or horizontal-scroll boundary flushes pending movement first, preventing the queue from moving a click ahead of the pointer position that selected its target.
- Large motion is split into report-sized segments.
- One worker drains batches, so every touch event does not create a new sending coroutine.
- Input arriving in the same UI frame can merge before the worker starts.
- When a bounded batch is full, stale remainder is counted as dropped motion rather than replayed later.
Buttons, clicks, and wheels
Button state is represented as a three-button snapshot. A release for an already accepted press is priority work, because queue pressure must never leave the host button stuck down. Single and double clicks expand into deterministic down, report, hold, up, and gap commands.
| Gesture | Protocol treatment |
|---|---|
| Single click | 60 ms held press followed by release |
| Double click | Two clicks with a 100 ms inter-click gap |
| Vertical scroll | Mouse wheel in the relative mouse report |
| Horizontal scroll | Temporary Shift modifier plus wheel, then restore the user's modifier mask |
Session and lifecycle safety
The service owns the transport beyond one Activity frame and exposes connection state as flows. Verified hosts are kept in Android DataStore. The three Dotori HID apps coordinate signed-sibling ownership so only one active control surface claims the scarce device role.
- A minimum report verifies a newly connected host.
- Session generation and service-instance checks reject late callbacks.
- Shutdown sends neutral state, disconnects, and unregisters in order.
- Background-start restrictions are surfaced instead of hidden behind a false connected state.
Verification and known limits
Tests cover accumulator capacity, motion segmentation and dropping, button snapshots, click timing, horizontal-scroll modifier restoration, reconnect policy, sibling handoff, persistence fallback, and lifecycle routing.
- Horizontal scrolling works only where the host application interprets Shift + wheel that way.
- Pointer acceleration and edge behavior are controlled by the host.
- Dropping excess stale movement is intentional under sustained overload.