fix(audio,flutter): parse Android UsbHeadset and Hdmi route strings

apps/chanora_flutter/lib/services/audio_lifecycle_service.dart: extend parseBridgeAudioRoute to handle 'UsbHeadset' (maps to wiredHeadset — USB audio is functionally a wired-class device, matching AndroidAudioLifecycleController.classifyCurrentRoute's own preference ordering at line 176) and 'Hdmi' (maps to unknown — HDMI is a display-out transport, not a voice-call audio path; no existing BridgeAudioRoute variant fits; safer to leave as unknown than to misclassify as Speaker). Previously these Android-emitted strings hit the default branch and silently became BridgeAudioRoute.unknown.

apps/chanora_flutter/test/services/audio_lifecycle_service_test.dart: split the existing single test into three — iOS-classified strings (preserved), Android UsbHeadset (new), Android Hdmi (new). flutter test: 3 passed, 0 failed.
This commit is contained in:
Edison Jwa
2026-06-07 23:11:12 +09:00
parent 957d68f39d
commit e3286f1197
2 changed files with 23 additions and 1 deletions
@@ -14,11 +14,15 @@ rust.BridgeAudioRoute parseBridgeAudioRoute(String value) {
case 'Speaker': case 'Speaker':
return rust.BridgeAudioRoute.speaker; return rust.BridgeAudioRoute.speaker;
case 'WiredHeadset': case 'WiredHeadset':
case 'UsbHeadset':
return rust.BridgeAudioRoute.wiredHeadset; return rust.BridgeAudioRoute.wiredHeadset;
case 'BluetoothHfp': case 'BluetoothHfp':
return rust.BridgeAudioRoute.bluetoothHfp; return rust.BridgeAudioRoute.bluetoothHfp;
case 'BluetoothA2dp': case 'BluetoothA2dp':
return rust.BridgeAudioRoute.bluetoothA2Dp; return rust.BridgeAudioRoute.bluetoothA2Dp;
case 'Hdmi':
case 'Unknown':
return rust.BridgeAudioRoute.unknown;
default: default:
return rust.BridgeAudioRoute.unknown; return rust.BridgeAudioRoute.unknown;
} }
@@ -4,7 +4,7 @@ import 'package:chanora_flutter/services/audio_lifecycle_service.dart';
import 'package:chanora_flutter/src/rust/api.dart' as rust; import 'package:chanora_flutter/src/rust/api.dart' as rust;
void main() { void main() {
test('parseBridgeAudioRoute maps platform route names', () { test('parseBridgeAudioRoute maps iOS-classified route strings', () {
expect(parseBridgeAudioRoute('Earpiece'), rust.BridgeAudioRoute.earpiece); expect(parseBridgeAudioRoute('Earpiece'), rust.BridgeAudioRoute.earpiece);
expect(parseBridgeAudioRoute('Speaker'), rust.BridgeAudioRoute.speaker); expect(parseBridgeAudioRoute('Speaker'), rust.BridgeAudioRoute.speaker);
expect( expect(
@@ -22,4 +22,22 @@ void main() {
expect(parseBridgeAudioRoute('Unknown'), rust.BridgeAudioRoute.unknown); expect(parseBridgeAudioRoute('Unknown'), rust.BridgeAudioRoute.unknown);
expect(parseBridgeAudioRoute('Other'), rust.BridgeAudioRoute.unknown); expect(parseBridgeAudioRoute('Other'), rust.BridgeAudioRoute.unknown);
}); });
test('parseBridgeAudioRoute maps Android UsbHeadset to wiredHeadset', () {
// AndroidAudioLifecycleController.classifyDevice emits 'UsbHeadset' for
// AudioDeviceInfo.TYPE_USB_HEADSET. USB audio is functionally a
// wired-class device — the Kotlin classifier's own preference ordering
// (line 176 of AndroidAudioLifecycleController.kt) groups it with
// WiredHeadset/BluetoothHfp/BluetoothA2dp.
expect(parseBridgeAudioRoute('UsbHeadset'),
rust.BridgeAudioRoute.wiredHeadset);
});
test('parseBridgeAudioRoute maps Android Hdmi to unknown', () {
// HDMI is a display-out transport, not a voice-call audio path; no
// existing BridgeAudioRoute variant fits. Treat as unknown rather
// than misclassify as Speaker.
expect(parseBridgeAudioRoute('Hdmi'), rust.BridgeAudioRoute.unknown);
});
} }