reconfigure method

Future<void> reconfigure({
  1. bool force = false,
  2. AudioSpeakerKind? preferredSpeaker,
})

Configures the current AudioSession to reflect the AudioModes applied.

Implementation

Future<void> reconfigure({
  bool force = false,
  AudioSpeakerKind? preferredSpeaker,
}) async {
  Log.debug(
    'reconfigure($force, $preferredSpeaker) -> intents are [${_intents.values.map((e) => e.mode.name).join(', ')}]',
    '$runtimeType',
  );

  if (_intents.isEmpty) {
    if (!PlatformUtils.isWeb) {
      // Reset back to speaker, but only if headphones are disconnected.
      if (speaker.value != AudioSpeakerKind.headphones) {
        await setSpeaker(AudioSpeakerKind.speaker);
      }

      if (PlatformUtils.isIOS) {
        await AVAudioSession().setActive(false);
      }
    }
  } else {
    final bool needsMic = _intents.values.any((e) => e.mode.needsMic);

    final AudioSessionConfiguration configuration = AudioSessionConfiguration(
      avAudioSessionCategory: needsMic
          ? AVAudioSessionCategory.playAndRecord
          : AVAudioSessionCategory.playback,
      avAudioSessionMode: needsMic
          ? AVAudioSessionMode.voiceChat
          : AVAudioSessionMode.defaultMode,
      avAudioSessionCategoryOptions:
          AVAudioSessionCategoryOptions.mixWithOthers |
          AVAudioSessionCategoryOptions.allowBluetooth |
          AVAudioSessionCategoryOptions.allowBluetoothA2dp,
      androidAudioAttributes: AndroidAudioAttributes(
        contentType: needsMic
            ? AndroidAudioContentType.speech
            : AndroidAudioContentType.music,
        usage: needsMic
            ? AndroidAudioUsage.voiceCommunication
            : AndroidAudioUsage.media,
      ),
      androidAudioFocusGainType: AndroidAudioFocusGainType.gainTransient,
    );

    if (configuration.toJson() == _previousConfiguration?.toJson()) {
      Log.debug(
        'reconfigure() -> ignoring ${_intents.values.map((e) => e.mode.name).join(', ')}',
        '$runtimeType',
      );

      return;
    }

    _previousConfiguration = configuration;

    final AudioSession session = await AudioSession.instance;

    try {
      await session.configure(configuration);
      await session.setActive(true, fallbackConfiguration: configuration);
    } catch (e) {
      Log.warning(
        'Failed to `session.configure()` due to: $e',
        '$runtimeType',
      );
    }

    if (preferredSpeaker != null) {
      // If we're using headphones, and the preferred one is speaker, then
      // shouldn't switch.
      if (speaker.value == AudioSpeakerKind.headphones &&
          preferredSpeaker == AudioSpeakerKind.speaker) {
        // No-op.
      } else {
        await setSpeaker(preferredSpeaker);
      }
    } else if (_isMobile) {
      if (speaker.value != null) {
        await setSpeaker(speaker.value!, force: force);
      }
    }
  }
}