Files
kryz-go-flutter/lib/carplay_bridge.dart
2026-05-17 18:35:16 -07:00

80 lines
2.0 KiB
Dart

import 'package:flutter/services.dart';
import 'streaming_audio_business_object.dart';
class CarPlayBridge {
CarPlayBridge({required StreamingAudioBusinessObject audio}) : _audio = audio;
static const MethodChannel _channel = MethodChannel(
'kryz_go_flutter/carplay/methods',
);
final StreamingAudioBusinessObject _audio;
bool _isStarted = false;
Future<void> start() async {
if (_isStarted) {
return;
}
_isStarted = true;
_channel.setMethodCallHandler(_handleNativeMethodCall);
_audio.addListener(_onAudioChanged);
await _pushSnapshotToNative();
}
Future<void> dispose() async {
if (!_isStarted) {
return;
}
_isStarted = false;
_audio.removeListener(_onAudioChanged);
_channel.setMethodCallHandler(null);
}
Map<String, dynamic> _snapshot() {
final String playbackStatus = switch (_audio.playbackStatus) {
StreamingPlaybackStatus.playing => 'playing',
StreamingPlaybackStatus.buffering => 'buffering',
StreamingPlaybackStatus.stopped => 'stopped',
};
return <String, dynamic>{
'playbackStatus': playbackStatus,
'isPlaying': _audio.isPlaying,
'isBuffering': _audio.isBuffering,
'isLive': true,
'seekable': false,
'title': _audio.currentTitle,
'subtitle': _audio.currentSubtitle,
'album': 'Live',
};
}
Future<dynamic> _handleNativeMethodCall(MethodCall call) async {
switch (call.method) {
case 'getStateSnapshot':
return _snapshot();
default:
throw MissingPluginException(
'Unknown CarPlay bridge method: ${call.method}',
);
}
}
void _onAudioChanged() {
_pushSnapshotToNative();
}
Future<void> _pushSnapshotToNative() async {
try {
await _channel.invokeMethod<void>('syncState', _snapshot());
} on MissingPluginException {
// CarPlay bridge only exists on iOS native builds.
} on PlatformException {
// Keep playback working even if native sync temporarily fails.
}
}
}