IsolatedAudioHandler constructor

IsolatedAudioHandler(
  1. AudioHandler inner, {
  2. String portName = defaultPortName,
  3. bool overridePortName = false,
})

Creates an IsolatedAudioHandler that can be looked up by portName (defaulting to defaultPortName).

This will throw a StateError if another IsolatedAudioHandler was already registered with the given port name. Setting overridePortName to true will unregister any existing port name first. However, this is inherently racy and may still throw the same StateError if another isolate is able to register another new handler with the same name before this isolate can.

Implementation

IsolatedAudioHandler(
  AudioHandler inner, {
  this.portName = defaultPortName,
  bool overridePortName = false,
})  : assert(!kIsWeb),
      super(inner) {
  _receivePort.listen((dynamic event) async {
    final request = event as _IsolateRequest;
    switch (request.method) {
      case 'playbackState':
        _syncStream(playbackState, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'queue':
        _syncStream(queue, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'queueTitle':
        _syncStream(queueTitle, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'mediaItem':
        _syncStream(mediaItem, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'androidPlaybackInfo':
        _syncStream(androidPlaybackInfo, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'ratingStyle':
        _syncStream(ratingStyle, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'customEvent':
        _syncStream<dynamic>(customEvent, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'customState':
        _syncStream<dynamic>(customState, request.arguments![0] as SendPort);
        request.sendPort.send(null);
        break;
      case 'prepare':
        await prepare();
        request.sendPort.send(null);
        break;
      case 'prepareFromMediaId':
        await prepareFromMediaId(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'prepareFromSearch':
        await prepareFromSearch(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'prepareFromUri':
        await prepareFromUri(
          request.arguments![0] as Uri,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'play':
        await play();
        request.sendPort.send(null);
        break;
      case 'playFromMediaId':
        await playFromMediaId(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'playFromSearch':
        await playFromSearch(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'playFromUri':
        await playFromUri(
          request.arguments![0] as Uri,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'playMediaItem':
        await playMediaItem(request.arguments![0] as MediaItem);
        request.sendPort.send(null);
        break;
      case 'pause':
        await pause();
        request.sendPort.send(null);
        break;
      case 'click':
        await click(request.arguments![0] as MediaButton);
        request.sendPort.send(null);
        break;
      case 'stop':
        await stop();
        request.sendPort.send(null);
        break;
      case 'addQueueItem':
        await addQueueItem(request.arguments![0] as MediaItem);
        request.sendPort.send(null);
        break;
      case 'addQueueItems':
        await addQueueItems(request.arguments![0] as List<MediaItem>);
        request.sendPort.send(null);
        break;
      case 'insertQueueItem':
        await insertQueueItem(
          request.arguments![0] as int,
          request.arguments![1] as MediaItem,
        );
        request.sendPort.send(null);
        break;
      case 'updateQueue':
        await updateQueue(request.arguments![0] as List<MediaItem>);
        request.sendPort.send(null);
        break;
      case 'updateMediaItem':
        await updateMediaItem(request.arguments![0] as MediaItem);
        request.sendPort.send(null);
        break;
      case 'removeQueueItem':
        await removeQueueItem(request.arguments![0] as MediaItem);
        request.sendPort.send(null);
        break;
      case 'removeQueueItemAt':
        await removeQueueItemAt(request.arguments![0] as int);
        request.sendPort.send(null);
        break;
      case 'skipToNext':
        await skipToNext();
        request.sendPort.send(null);
        break;
      case 'skipToPrevious':
        await skipToPrevious();
        request.sendPort.send(null);
        break;
      case 'fastForward':
        await fastForward();
        request.sendPort.send(null);
        break;
      case 'rewind':
        await rewind();
        request.sendPort.send(null);
        break;
      case 'skipToQueueItem':
        await skipToQueueItem(request.arguments![0] as int);
        request.sendPort.send(null);
        break;
      case 'seek':
        await seek(request.arguments![0] as Duration);
        request.sendPort.send(null);
        break;
      case 'setRating':
        await setRating(
          request.arguments![0] as Rating,
          request.arguments![1] as Map<String, dynamic>?,
        );
        request.sendPort.send(null);
        break;
      case 'setCaptioningEnabled':
        await setCaptioningEnabled(request.arguments![0] as bool);
        request.sendPort.send(null);
        break;
      case 'setRepeatMode':
        await setRepeatMode(request.arguments![0] as AudioServiceRepeatMode);
        request.sendPort.send(null);
        break;
      case 'setShuffleMode':
        await setShuffleMode(
            request.arguments![0] as AudioServiceShuffleMode);
        request.sendPort.send(null);
        break;
      case 'seekBackward':
        await seekBackward(request.arguments![0] as bool);
        request.sendPort.send(null);
        break;
      case 'seekForward':
        await seekForward(request.arguments![0] as bool);
        request.sendPort.send(null);
        break;
      case 'setSpeed':
        await setSpeed(request.arguments![0] as double);
        request.sendPort.send(null);
        break;
      case 'customAction':
        request.sendPort.send(await customAction(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        ));
        break;
      case 'onTaskRemoved':
        await onTaskRemoved();
        request.sendPort.send(null);
        break;
      case 'onNotificationDeleted':
        await onNotificationDeleted();
        request.sendPort.send(null);
        break;
      case 'getChildren':
        request.sendPort.send(await getChildren(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        ));
        break;
      case 'subscribeToChildren':
        final parentMediaId = request.arguments![0] as String;
        final sendPort = request.arguments![1] as SendPort?;
        subscribeToChildren(parentMediaId).listen(sendPort!.send);
        break;
      case 'getMediaItem':
        final result = await getMediaItem(request.arguments![0] as String);
        request.sendPort.send(result);
        break;
      case 'search':
        request.sendPort.send(await search(
          request.arguments![0] as String,
          request.arguments![1] as Map<String, dynamic>?,
        ));
        break;
      case 'androidAdjustRemoteVolume':
        await androidAdjustRemoteVolume(
            request.arguments![0] as AndroidVolumeDirection);
        request.sendPort.send(null);
        break;
      case 'androidSetRemoteVolume':
        await androidSetRemoteVolume(request.arguments![0] as int);
        request.sendPort.send(null);
        break;
    }
  });
  if (overridePortName) {
    IsolateNameServer.removePortNameMapping(portName);
  }
  final success =
      IsolateNameServer.registerPortWithName(_receivePort.sendPort, portName);
  if (!success) {
    throw StateError(
        'Port name $portName is already registered by another IsolatedAudioHandler.');
  }
}