Add A2DP sink mode — BlueZ pairing agent + bluealsa delegation
Registers a BlueZ pairing agent at server boot when
`[bluetooth.a2dp].enabled = true`. The agent's RequestConfirmation
callback publishes `BluetoothPairingRequest` onto the event bus and
either auto-accepts (kiosk mode) or parks on a per-address oneshot
waiting for `BluetoothService.RespondPairing` — 30s timeout falls back
to rejection so a stuck prompt doesn't leak the channel.
AuthorizeService accepts the A2DP Source UUID
(`0000110a-…`) and emits `BluetoothA2dpConnected` so phones can stream
audio without a second confirm after pairing.
Adapter setup at boot: optional alias, set_pairable(true), and
discoverable + discoverable_timeout when requested.
New RPCs: `SetDiscoverable`, `RespondPairing`, `A2dpEnable`,
`A2dpDisable`. A2dpEnable preflights `bluealsa-aplay.service` via the
existing systemd allowlist and surfaces a clear "install
bluez-alsa-utils" error if the unit is missing. The unit is
auto-appended to the systemd allowlist whenever a2dp is enabled, so
users don't need to remember to list it under [systemd].
Non-Linux: start_agent is a silent no-op so the server still boots
with `a2dp.enabled = true` on macOS for development; RPC-level paths
return "linux only".
bluer pinned to =0.17.4 exact — the Agent callback shape varies
across minor versions and a silent rewire of the pairing flow is
worse than a build break.
Verified: host build green; cross --target arm-unknown-linux-gnueabihf
green; macOS smoke covers disabled-by-config, stub fall-through,
preflight error path, and auto-allowlist.
This is a binary file and will not be displayed.