Bluetooth HID and Korean input

Why a phone keyboard needs both a transport state machine and an explicit model of what the receiving host will do.

Source baseline: app 1.0.0 (1) · 14 August 2026

System boundary

The phone is the Bluetooth HID device; the PC, TV, or tablet is the host. The app sends keyboard and mouse reports, but it cannot inspect the host's focused field or reliably read its IME mode. That boundary is the reason calibration and host profiles are first-class state rather than UI preferences.

UI and lifecycleKotlin, Jetpack Compose, Android foreground service
HID payloadShared keyboard-and-mouse descriptor with separate report IDs
Persistent stateVerified hosts, selected profile, calibration and app preferences
Network dependencyNone for HID input; ads are a separate optional runtime

Transport selection

The shared HID layer asks Android for the Classic Bluetooth HID Device profile first. If that profile is unavailable after a bounded grace period, it can select BLE HOGP instead. The chosen transport is published as state so pairing, reconnect, and discoverability rules do not guess which path is active.

Text encoding and host profiles

Text is normalized, divided into English and Korean runs, and compiled into an encoding plan before reports are sent. A modern precomposed Hangul syllable is decomposed into two-set jamo keystrokes; English characters use a US key map. The plan also contains required IME transitions and its final assumed IME state.

The app models, rather than observes, the host IME. Keyboard LED output can refine the assumption on supported hosts, but calibration remains necessary because platforms map language-switch keys differently. The on-screen keycaps are drawn from that same assumption, which is why they can drift out of step with the host.

Profiles make those differences explicit: Windows Korean, Windows US, iOS US, and Android TV US select key maps and mode-switch candidates. Unsupported code points reject the plan before partial text is emitted.

Session ownership and safe release

A foreground service owns registration, host connection, and report dispatch. Keyboard, PPT, and Mouse are separate apps but Android exposes a scarce HID role, so signed sibling apps use a handoff contract: the new owner requests release and the old owner follows its normal shutdown path.

Verification and known limits

Unit and integration tests cover Hangul decomposition, key maps, encoding plans, descriptor reports, queue ordering, reconnect policy, sibling handoff, process recreation, and calibration decisions. Device behavior still depends on the phone exposing a usable HID transport and the host honoring the advertised descriptor.