80 lines
2.0 KiB
Dart
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.
|
|
}
|
|
}
|
|
}
|