LCOV - code coverage report
Current view: top level - _remote_media_client - android_remote_media_client_method_channel.dart Coverage Total Hit
Test: lcov_cleaned.info Lines: 100.0 % 104 104
Test Date: 2025-06-20 10:50:47 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:convert';
       2              : 
       3              : import 'package:flutter/services.dart';
       4              : import 'package:flutter_chrome_cast/_remote_media_client/remote_media_client_platform.dart';
       5              : import 'package:flutter_chrome_cast/entities/cast_media_status.dart';
       6              : import 'package:flutter_chrome_cast/entities/load_options.dart';
       7              : import 'package:flutter_chrome_cast/entities/media_information.dart';
       8              : import 'package:flutter_chrome_cast/entities/queue_item.dart';
       9              : import 'package:flutter_chrome_cast/entities/media_seek_option.dart';
      10              : import 'package:flutter_chrome_cast/entities/request.dart';
      11              : import 'package:flutter_chrome_cast/models/android/android_media_status.dart';
      12              : import 'package:flutter_chrome_cast/models/android/android_queue_item.dart';
      13              : import 'package:rxdart/subjects.dart';
      14              : 
      15              : /// Android-specific implementation of Google Cast remote media client functionality.
      16              : class GoogleCastRemoteMediaClientAndroidMethodChannel
      17              :     implements GoogleCastRemoteMediaClientPlatformInterface {
      18              :   /// Creates a new Android remote media client method channel.
      19            1 :   GoogleCastRemoteMediaClientAndroidMethodChannel() {
      20            3 :     _channel.setMethodCallHandler(_onMethodCallHandler);
      21              :   }
      22              : 
      23              :   final _channel =
      24              :       const MethodChannel('com.felnanuke.google_cast.remote_media_client');
      25              : 
      26              :   // Media Status
      27              :   final _mediaStatusStreamController = BehaviorSubject<GoggleCastMediaStatus?>()
      28              :     ..add(null);
      29              : 
      30            1 :   @override
      31            2 :   GoggleCastMediaStatus? get mediaStatus => _mediaStatusStreamController.value;
      32              : 
      33            1 :   @override
      34              :   Stream<GoggleCastMediaStatus?> get mediaStatusStream =>
      35            2 :       _mediaStatusStreamController.stream;
      36              : 
      37              : // QueueItems
      38              :   final _queueItemsStreamController =
      39              :       BehaviorSubject<List<GoogleCastQueueItem>>()..add([]);
      40              : 
      41            1 :   @override
      42            2 :   List<GoogleCastQueueItem> get queueItems => _queueItemsStreamController.value;
      43              : 
      44            1 :   @override
      45              :   Stream<List<GoogleCastQueueItem>> get queueItemsStream =>
      46            2 :       _queueItemsStreamController.stream;
      47              : 
      48              : // PlayerPosition
      49              :   final _playerPositionStreamController = BehaviorSubject<Duration>()
      50              :     ..add(Duration.zero);
      51            1 :   @override
      52            2 :   Duration get playerPosition => _playerPositionStreamController.value;
      53              : 
      54            1 :   @override
      55              :   Stream<Duration> get playerPositionStream =>
      56            2 :       _playerPositionStreamController.stream;
      57              : 
      58              :   // Queue has Next or revious item
      59            1 :   @override
      60              :   bool get queueHasNextItem {
      61            2 :     final currentQueueItemId = mediaStatus?.currentItemId;
      62            1 :     final currentItemIndex = queueItems
      63            3 :         .map((e) => e.itemId)
      64            1 :         .toList()
      65            1 :         .lastIndexOf(currentQueueItemId);
      66            4 :     return (queueItems.length - 1) > currentItemIndex;
      67              :   }
      68              : 
      69            1 :   @override
      70              :   bool get queueHasPreviousItem => true;
      71              : 
      72            1 :   @override
      73              :   Future<GoogleCastRequest?> loadMedia(
      74              :     GoogleCastMediaInformation mediaInfo, {
      75              :     bool autoPlay = true,
      76              :     Duration playPosition = Duration.zero,
      77              :     double playbackRate = 1.0,
      78              :     List<int>? activeTrackIds,
      79              :     String? credentials,
      80              :     String? credentialsType,
      81              :   }) async {
      82            2 :     final result = await _channel.invokeMethod(
      83              :       'loadMedia',
      84            1 :       {
      85            1 :         'mediaInfo': mediaInfo.toMap(),
      86              :         'autoPlay': autoPlay,
      87            1 :         'playPosition': playPosition.inSeconds,
      88              :         'playbackRate': playbackRate,
      89              :         'activeTrackIds': activeTrackIds,
      90              :         'credentials': credentials,
      91              :         'credentialsType': credentialsType
      92              :       },
      93              :     );
      94              :     return result != null
      95            2 :         ? GoogleCastRequest.fromMap(Map<String, dynamic>.from(result))
      96              :         : null;
      97              :   }
      98              : 
      99            1 :   @override
     100              :   Future<GoogleCastRequest> pause() async {
     101            2 :     final result = await _channel.invokeMethod('pause');
     102            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     103              :   }
     104              : 
     105            1 :   @override
     106              :   Future<GoogleCastRequest> play() async {
     107            2 :     final result = await _channel.invokeMethod('play');
     108            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     109              :   }
     110              : 
     111            1 :   @override
     112              :   Future<GoogleCastRequest?> queueLoadItems(
     113              :     List<GoogleCastQueueItem> queueItems, {
     114              :     GoogleCastQueueLoadOptions? options,
     115              :   }) async {
     116            3 :     final result = await _channel.invokeMethod('queueLoadItems', {
     117            4 :       'queueItems': queueItems.map((item) => item.toMap()).toList(),
     118            1 :       'options': options?.toMap(),
     119              :     });
     120              :     return result != null
     121            2 :         ? GoogleCastRequest.fromMap(Map<String, dynamic>.from(result))
     122              :         : null;
     123              :   }
     124              : 
     125            1 :   @override
     126              :   Future<GoogleCastRequest> queueNextItem() async {
     127            2 :     final result = await _channel.invokeMethod('queueNextItem');
     128            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     129              :   }
     130              : 
     131            1 :   @override
     132              :   Future<GoogleCastRequest> queuePrevItem() async {
     133            2 :     final result = await _channel.invokeMethod('queuePrevItem');
     134            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     135              :   }
     136              : 
     137            1 :   @override
     138              :   Future<GoogleCastRequest> seek(GoogleCastMediaSeekOption option) async {
     139            2 :     final result = await _channel.invokeMethod(
     140              :       'seek',
     141            1 :       option.toMap(),
     142              :     );
     143            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     144              :   }
     145              : 
     146            1 :   @override
     147              :   Future<GoogleCastRequest> setActiveTrackIDs(List<int> activeTrackIDs) async {
     148            2 :     final result = await _channel.invokeMethod(
     149              :       'setActiveTrackIds',
     150              :       activeTrackIDs,
     151              :     );
     152            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     153              :   }
     154              : 
     155            1 :   @override
     156              :   Future<GoogleCastRequest> setPlaybackRate(double rate) async {
     157            2 :     final result = await _channel.invokeMethod('setPlaybackRate', rate);
     158            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     159              :   }
     160              : 
     161            1 :   @override
     162              :   Future<GoogleCastRequest> setTextTrackStyle(
     163              :       TextTrackStyle textTrackStyle) async {
     164            2 :     final result = await _channel.invokeMethod(
     165              :       'setTextTrackStyle',
     166            1 :       textTrackStyle.toMap(),
     167              :     );
     168            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     169              :   }
     170              : 
     171            1 :   @override
     172              :   Future<GoogleCastRequest> stop() async {
     173            2 :     final result = await _channel.invokeMethod('stop');
     174            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     175              :   }
     176              : 
     177            1 :   @override
     178              :   Future<GoogleCastRequest> queueJumpToItemWithId(int itemId) async {
     179            2 :     final result = await _channel.invokeMethod('queueJumpToItemWithId', itemId);
     180            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     181              :   }
     182              : 
     183            1 :   @override
     184              :   Future<GoogleCastRequest> queueRemoveItemsWithIds(List<int> itemIds) async {
     185              :     final result =
     186            2 :         await _channel.invokeMethod('queueRemoveItemsWithIds', itemIds);
     187            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     188              :   }
     189              : 
     190            1 :   @override
     191              :   Future<GoogleCastRequest> queueInsertItemAndPlay(GoogleCastQueueItem item,
     192              :       {required int beforeItemWithId}) async {
     193            3 :     final result = await _channel.invokeMethod('queueInsertItemAndPlay', {
     194            1 :       'item': item.toMap(),
     195              :       'beforeItemWithId': beforeItemWithId,
     196              :     });
     197            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     198              :   }
     199              : 
     200            1 :   @override
     201              :   Future<GoogleCastRequest> queueInsertItems(List<GoogleCastQueueItem> items,
     202              :       {int? beforeItemWithId}) async {
     203            3 :     final result = await _channel.invokeMethod('queueInsertItems', {
     204            4 :       'items': items.map((item) => item.toMap()).toList(),
     205              :       'beforeItemWithId': beforeItemWithId,
     206              :     });
     207            2 :     return GoogleCastRequest.fromMap(Map<String, dynamic>.from(result));
     208              :   }
     209              : 
     210            1 :   Future _onMethodCallHandler(MethodCall call) async {
     211            1 :     switch (call.method) {
     212            1 :       case 'onMediaStatusChanged':
     213            2 :         return _onMediaStatusChanged(call.arguments);
     214            1 :       case 'onQueueStatusChanged':
     215            2 :         return _onQueueStatusChanged(call.arguments);
     216            1 :       case 'onPlayerPositionChanged':
     217            2 :         return _onPlayerPositionChanged(call.arguments);
     218              :       default:
     219              :     }
     220              :   }
     221              : 
     222            1 :   Future<void> _onMediaStatusChanged(dynamic arguments) async {
     223              :     if (arguments == null) {
     224            2 :       _mediaStatusStreamController.add(null);
     225              :       return;
     226              :     }
     227            1 :     final mediaStatus = GoogleCastAndroidMediaStatus.fromMap(
     228            2 :       Map<String, dynamic>.from(jsonDecode(arguments)),
     229              :     );
     230              : 
     231            2 :     _mediaStatusStreamController.add(mediaStatus);
     232              :   }
     233              : 
     234            1 :   Future<void> _onQueueStatusChanged(dynamic arguments) async {
     235              :     if (arguments == null) {
     236            3 :       _queueItemsStreamController.add([]);
     237              :       return;
     238              :     }
     239              : 
     240            1 :     final map = List.from(arguments);
     241              : 
     242              :     final queueItems = map
     243            3 :         .map((e) => GoogleCastAndroidQueueItem.fromMap(
     244            1 :             Map<String, dynamic>.from(
     245            2 :                 Map<String, dynamic>.from(jsonDecode(e)))))
     246            1 :         .toList();
     247            2 :     _queueItemsStreamController.add(queueItems);
     248              :   }
     249              : 
     250            1 :   Future<void> _onPlayerPositionChanged(dynamic arguments) async {
     251              :     if (arguments == null) {
     252            2 :       _playerPositionStreamController.add(Duration.zero);
     253              :       return;
     254              :     }
     255            1 :     arguments = Map<String, dynamic>.from(arguments);
     256              : 
     257            2 :     final playerPosition = Duration(milliseconds: arguments["progress"] ?? 0);
     258            2 :     _playerPositionStreamController.add(playerPosition);
     259              :   }
     260              : 
     261            1 :   @override
     262              :   Future<void> queueReorderItems(
     263              :       {required List<int> itemsIds, required int? beforeItemWithId}) {
     264            3 :     return _channel.invokeMethod('queueReorderItems', {
     265              :       'itemsIds': itemsIds,
     266              :       'beforeItemWithId': beforeItemWithId,
     267              :     });
     268              :   }
     269              : }
        

Generated by: LCOV version 2.3.1-1