feat(android): add settings bluetooth on|off

MI
6h ago
+794-186

Summary

Adds settings bluetooth on|off for Android over adb, local and Limrun, next to wifi, airplane and mobile-data. Turning the adapter off lets a test drop a Bluetooth headset mid-playback.

agent-device settings bluetooth off   # { "bluetooth": "disabled" }
  • Runs svc bluetooth enable|disable from Android 8.1, API 27. On Android 13+ svc forwards to cmd bluetooth_manager, so one command covers every level.
  • svc bluetooth exits 0 even when the adapter refuses, so the change is confirmed by polling bluetooth_on for up to 2 s. If it never settles it fails with COMMAND_FAILED and reason bluetooth-not-applied or bluetooth-unreadable, like mobile-data.
  • Nothing is written, and the error says dispatched: no, without android.hardware.bluetooth, below 8.1, on an unreadable API level, or after cancellation. Other targets refuse it before anything runs.
  • pm list features gets one parser, shared with TV discovery. The API-level read moves to device-sdk-int.ts, and three underFakeTimers helpers become one.

22 files.

Validation

At 8e302d9e, on 77137b01, format, lint, layering, fallow, build, command-docs and related unit tests pass. Typecheck fails only in test/integration/command-coverage/declarations.ts, which is unchanged from main and broken there too. Coverage, integration and smoke run in CI.

Unit tests cover each refusal with the adb calls it made, the read-back, dispatch disclosure and cancellation. Reverting each fix fails at least one.

On an API 37 emulator at 07e3bb1f, settings bluetooth off and on report disabled and enabled, and bluetooth_on reads 0 then 1. On API 27 and API 26 images without android.hardware.bluetooth, it refuses with android_bluetooth_adapter_missing and dispatched: no and leaves bluetooth_on unchanged. Raw svc bluetooth exits 0 there without doing anything, which is why the adapter and API checks run first. Not covered: Limrun.