Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b42bce5 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Fix suspend/resume loop

Depending on the order of calls to audio HAL sink and source resume requests,
we could end up in a long suspend/resume cycle that was mostly visible when
switching to Live recording scenario. This delayed the recording session
resume.

This change adjusts the resume logic to properly take into the account
sink and source coupling in the configuration phase and the independent
resumes from the audio frameworks on either directions.

Tag: #feature
Bug: 272029679
Test: manually tested
Test: atest --host bluetooth_le_audio_client_test bluetooth_le_audio_test --no-bazel-mode
Change-Id: I63ed242af49dd6805fb3d7aaaa5ce02ed01bf7c4
parent 06a99616
Loading
Loading
Loading
Loading
+161 −28
Original line number Original line Diff line number Diff line
@@ -3380,14 +3380,56 @@ class LeAudioClientImpl : public LeAudioClient {
            }
            }
            break;
            break;
          case AudioState::READY_TO_START:
          case AudioState::READY_TO_START:
            audio_sender_state_ = AudioState::READY_TO_START;
            if (!IsDirectionAvailableForCurrentConfiguration(
                    group, le_audio::types::kLeAudioDirectionSink)) {
              LOG_WARN(
                  " sink is not configured. \n audio_receiver_state: %s \n"
                  "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                  "Reconfiguring to %s",
                  ToString(audio_receiver_state_).c_str(),
                  ToString(audio_sender_state_).c_str(),
                  (group->IsPendingConfiguration() ? "true" : "false"),
                  ToString(configuration_context_type_).c_str());
              group->PrintDebugState();
              SetConfigurationAndStopStreamWhenNeeded(
                  group, configuration_context_type_);
            }
            break;
          case AudioState::STARTED:
          case AudioState::STARTED:
            audio_sender_state_ = AudioState::READY_TO_START;
            audio_sender_state_ = AudioState::READY_TO_START;
            /* If signalling part is completed trigger start receiving audio
            /* If signalling part is completed trigger start sending audio
             * here, otherwise it'll be called on group streaming state callback
             * here, otherwise it'll be called on group streaming state callback
             */
             */
            if (group->GetState() ==
            if (group->GetState() ==
                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
              if (IsDirectionAvailableForCurrentConfiguration(
                      group, le_audio::types::kLeAudioDirectionSink)) {
                StartSendingAudio(active_group_id_);
                StartSendingAudio(active_group_id_);
              } else {
                LOG_WARN(
                    " sink is not configured. \n audio_receiver_state: %s \n"
                    "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                    "Reconfiguring to %s",
                    ToString(audio_receiver_state_).c_str(),
                    ToString(audio_sender_state_).c_str(),
                    (group->IsPendingConfiguration() ? "true" : "false"),
                    ToString(configuration_context_type_).c_str());
                group->PrintDebugState();
                SetConfigurationAndStopStreamWhenNeeded(
                    group, configuration_context_type_);
              }
            } else {
              LOG_ERROR(
                  " called in wrong state. \n audio_receiver_state: %s \n"
                  "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                  "Reconfiguring to %s",
                  ToString(audio_receiver_state_).c_str(),
                  ToString(audio_sender_state_).c_str(),
                  (group->IsPendingConfiguration() ? "true" : "false"),
                  ToString(configuration_context_type_).c_str());
              group->PrintDebugState();
              CancelStreamingRequest();
            }
            }
            break;
            break;
          case AudioState::RELEASING:
          case AudioState::RELEASING:
@@ -3397,21 +3439,50 @@ class LeAudioClientImpl : public LeAudioClient {
            audio_sender_state_ = audio_receiver_state_;
            audio_sender_state_ = audio_receiver_state_;
            break;
            break;
          case AudioState::READY_TO_RELEASE:
          case AudioState::READY_TO_RELEASE:
            /* If the other direction is streaming we can start sending audio */
            if (group->GetState() ==
                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
              if (IsDirectionAvailableForCurrentConfiguration(
                      group, le_audio::types::kLeAudioDirectionSink)) {
                StartSendingAudio(active_group_id_);
              } else {
                LOG_WARN(
                LOG_WARN(
                    " sink is not configured. \n audio_receiver_state: %s \n"
                    "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                    "Reconfiguring to %s",
                    ToString(audio_receiver_state_).c_str(),
                    ToString(audio_sender_state_).c_str(),
                    (group->IsPendingConfiguration() ? "true" : "false"),
                    ToString(configuration_context_type_).c_str());
                group->PrintDebugState();
                SetConfigurationAndStopStreamWhenNeeded(
                    group, configuration_context_type_);
              }
            } else {
              LOG_ERROR(
                  " called in wrong state. \n audio_receiver_state: %s \n"
                  " called in wrong state. \n audio_receiver_state: %s \n"
                "audio_sender_state: %s \n",
                  "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                  "Reconfiguring to %s",
                  ToString(audio_receiver_state_).c_str(),
                  ToString(audio_receiver_state_).c_str(),
                ToString(audio_sender_state_).c_str());
                  ToString(audio_sender_state_).c_str(),
                  (group->IsPendingConfiguration() ? "true" : "false"),
                  ToString(configuration_context_type_).c_str());
              group->PrintDebugState();
              CancelStreamingRequest();
              CancelStreamingRequest();
            }
            break;
            break;
        }
        }
        break;
        break;
      case AudioState::READY_TO_START:
      case AudioState::READY_TO_START:
        LOG_WARN(
        LOG_ERROR(
            " called in wrong state. \n audio_receiver_state: %s \n"
            " called in wrong state. \n audio_receiver_state: %s \n"
            "audio_sender_state: %s \n",
            "audio_sender_state: %s \n isPendingConfiguration: %s \n "
            "Reconfiguring to %s",
            ToString(audio_receiver_state_).c_str(),
            ToString(audio_receiver_state_).c_str(),
            ToString(audio_sender_state_).c_str());
            ToString(audio_sender_state_).c_str(),
            (group->IsPendingConfiguration() ? "true" : "false"),
            ToString(configuration_context_type_).c_str());
        group->PrintDebugState();
        CancelStreamingRequest();
        CancelStreamingRequest();
        break;
        break;
      case AudioState::READY_TO_RELEASE:
      case AudioState::READY_TO_RELEASE:
@@ -3545,24 +3616,56 @@ class LeAudioClientImpl : public LeAudioClient {
            }
            }
            break;
            break;
          case AudioState::READY_TO_START:
          case AudioState::READY_TO_START:
            audio_receiver_state_ = AudioState::READY_TO_START;
            if (!IsDirectionAvailableForCurrentConfiguration(
                    group, le_audio::types::kLeAudioDirectionSource)) {
              LOG_WARN(
                  " source is not configured. \n audio_receiver_state: %s \n"
                  "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                  "Reconfiguring to %s",
                  ToString(audio_receiver_state_).c_str(),
                  ToString(audio_sender_state_).c_str(),
                  (group->IsPendingConfiguration() ? "true" : "false"),
                  ToString(configuration_context_type_).c_str());
              group->PrintDebugState();
              SetConfigurationAndStopStreamWhenNeeded(
                  group, configuration_context_type_);
            }
            break;
          case AudioState::STARTED:
          case AudioState::STARTED:
            audio_receiver_state_ = AudioState::READY_TO_START;
            audio_receiver_state_ = AudioState::READY_TO_START;
            /* If signalling part is completed trigger start reveivin audio
            /* If signalling part is completed trigger start receiving audio
             * here, otherwise it'll be called on group streaming state callback
             * here, otherwise it'll be called on group streaming state callback
             */
             */
            if (group->GetState() ==
            if (group->GetState() ==
                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
              if (!IsDirectionAvailableForCurrentConfiguration(
              if (IsDirectionAvailableForCurrentConfiguration(
                      group, le_audio::types::kLeAudioDirectionSource)) {
                      group, le_audio::types::kLeAudioDirectionSource)) {
                StartReceivingAudio(active_group_id_);
              } else {
                LOG_WARN(
                LOG_WARN(
                    "Local audio sink was resumed when not in a proper "
                    " source is not configured. \n audio_receiver_state: %s \n"
                    "configuration. This should not happen. Reconfiguring to "
                    "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                    "VOICEASSISTANTS.");
                    "Reconfiguring to %s",
                    ToString(audio_receiver_state_).c_str(),
                    ToString(audio_sender_state_).c_str(),
                    (group->IsPendingConfiguration() ? "true" : "false"),
                    ToString(configuration_context_type_).c_str());
                group->PrintDebugState();
                SetConfigurationAndStopStreamWhenNeeded(
                SetConfigurationAndStopStreamWhenNeeded(
                    group, LeAudioContextType::VOICEASSISTANTS);
                    group, configuration_context_type_);
                break;
              }
              }
              StartReceivingAudio(active_group_id_);
            } else {
              LOG_ERROR(
                  " called in wrong state. \n audio_receiver_state: %s \n"
                  "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                  "Reconfiguring to %s",
                  ToString(audio_receiver_state_).c_str(),
                  ToString(audio_sender_state_).c_str(),
                  (group->IsPendingConfiguration() ? "true" : "false"),
                  ToString(configuration_context_type_).c_str());
              group->PrintDebugState();
              CancelStreamingRequest();
            }
            }
            break;
            break;
          case AudioState::RELEASING:
          case AudioState::RELEASING:
@@ -3572,21 +3675,51 @@ class LeAudioClientImpl : public LeAudioClient {
            audio_receiver_state_ = audio_sender_state_;
            audio_receiver_state_ = audio_sender_state_;
            break;
            break;
          case AudioState::READY_TO_RELEASE:
          case AudioState::READY_TO_RELEASE:
            /* If the other direction is streaming we can start receiving audio
             */
            if (group->GetState() ==
                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
              if (IsDirectionAvailableForCurrentConfiguration(
                      group, le_audio::types::kLeAudioDirectionSource)) {
                StartReceivingAudio(active_group_id_);
              } else {
                LOG_WARN(
                LOG_WARN(
                    " source is not configured. \n audio_receiver_state: %s \n"
                    "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                    "Reconfiguring to %s",
                    ToString(audio_receiver_state_).c_str(),
                    ToString(audio_sender_state_).c_str(),
                    (group->IsPendingConfiguration() ? "true" : "false"),
                    ToString(configuration_context_type_).c_str());
                group->PrintDebugState();
                SetConfigurationAndStopStreamWhenNeeded(
                    group, configuration_context_type_);
              }
            } else {
              LOG_ERROR(
                  " called in wrong state. \n audio_receiver_state: %s \n"
                  " called in wrong state. \n audio_receiver_state: %s \n"
                "audio_sender_state: %s \n",
                  "audio_sender_state: %s \n isPendingConfiguration: %s \n "
                  "Reconfiguring to %s",
                  ToString(audio_receiver_state_).c_str(),
                  ToString(audio_receiver_state_).c_str(),
                ToString(audio_sender_state_).c_str());
                  ToString(audio_sender_state_).c_str(),
                  (group->IsPendingConfiguration() ? "true" : "false"),
                  ToString(configuration_context_type_).c_str());
              group->PrintDebugState();
              CancelStreamingRequest();
              CancelStreamingRequest();
            }
            break;
            break;
        }
        }
        break;
        break;
      case AudioState::READY_TO_START:
      case AudioState::READY_TO_START:
        LOG_WARN(
        LOG_ERROR(
            " called in wrong state. \n audio_receiver_state: %s \n"
            " called in wrong state. \n audio_receiver_state: %s \n"
            "audio_sender_state: %s \n",
            "audio_sender_state: %s \n isPendingConfiguration: %s \n "
            "Reconfiguring to %s",
            ToString(audio_receiver_state_).c_str(),
            ToString(audio_receiver_state_).c_str(),
            ToString(audio_sender_state_).c_str());
            ToString(audio_sender_state_).c_str(),
            (group->IsPendingConfiguration() ? "true" : "false"),
            ToString(configuration_context_type_).c_str());
        group->PrintDebugState();
        CancelStreamingRequest();
        CancelStreamingRequest();
        break;
        break;
      case AudioState::READY_TO_RELEASE:
      case AudioState::READY_TO_RELEASE: