setScreenShareEnabled method

Future<void> setScreenShareEnabled(
  1. bool enabled, {
  2. MediaDisplayDetails? device,
  3. bool withAudio = false,
})

Enables/disables local screen-sharing stream based on enabled.

Implementation

Future<void> setScreenShareEnabled(
  bool enabled, {
  MediaDisplayDetails? device,
  bool withAudio = false,
}) async {
  Log.debug(
    'setScreenShareEnabled($enabled, ${device?.deviceId()}, withAudio: $withAudio)',
    '$runtimeType',
  );

  switch (screenShareState.value) {
    case LocalTrackState.disabled:
    case LocalTrackState.disabling:
      if (enabled) {
        screenShareState.value = LocalTrackState.enabling;

        try {
          await _updateSettings(
            screen: true,
            screenDevice: device ?? displays.firstOrNull,
            screenAudio: withAudio,
          );

          await _room?.enableVideo(MediaSourceKind.display);
          if (hasScreenAudio) {
            await _room?.enableAudio(MediaSourceKind.display);
          }

          Log.debug(
            'setScreenShareEnabled($enabled, ${device?.deviceId()}, withAudio: $withAudio) -> $hasScreen || $hasScreenAudio -> ${members[_me]?.tracks.map((e) => '${e.kind}, ${e.source}')}',
            '$runtimeType',
          );

          screenShareState.value = hasScreen || hasScreenAudio
              ? LocalTrackState.enabled
              : LocalTrackState.disabled;
        } on MediaStateTransitionException catch (_) {
          // No-op.
        } on LocalMediaInitException catch (e) {
          screenShareState.value = LocalTrackState.disabled;

          _room?.disableVideo(MediaSourceKind.display);
          _removeLocalTracks(MediaKind.video, MediaSourceKind.display);
          if (hasScreenAudio) {
            _room?.disableAudio(MediaSourceKind.display);
            _removeLocalTracks(MediaKind.audio, MediaSourceKind.display);
          }

          if (!e.message().contains('Permission denied') &&
              !e.message().contains('NotAllowedError')) {
            _notifications.add(ScreenDeviceFailedNotification());
            Log.warning(
              'enableScreenShare() call failed with $e',
              '$runtimeType',
            );
            rethrow;
          }
        } catch (e) {
          screenShareState.value = LocalTrackState.disabled;

          _notifications.add(ScreenDeviceFailedNotification());
          Log.warning(
            'enableScreenShare() call failed with $e',
            '$runtimeType',
          );

          _room?.disableVideo(MediaSourceKind.display);
          _removeLocalTracks(MediaKind.video, MediaSourceKind.display);
          if (hasScreenAudio) {
            _room?.disableAudio(MediaSourceKind.display);
            _removeLocalTracks(MediaKind.audio, MediaSourceKind.display);
          }

          rethrow;
        }
      }
      break;

    case LocalTrackState.enabled:
    case LocalTrackState.enabling:
      if (!enabled) {
        screenShareState.value = LocalTrackState.disabling;
        screenAudio.value = false;

        try {
          await _room?.disableVideo(MediaSourceKind.display);
          _removeLocalTracks(MediaKind.video, MediaSourceKind.display);
          await _room?.disableAudio(MediaSourceKind.display);
          _removeLocalTracks(MediaKind.audio, MediaSourceKind.display);

          screenShareState.value = hasScreen || hasScreenAudio
              ? LocalTrackState.enabled
              : LocalTrackState.disabled;

          screenDevice.value = null;
        } on MediaStateTransitionException catch (_) {
          // No-op.
        } catch (e) {
          addError('disableScreenShare() call failed with $e');
          screenShareState.value = LocalTrackState.enabled;
          rethrow;
        }
      }
      break;
  }
}