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

Commit 51df9282 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "leaudio: Improve disconnection during streaming" into main

parents 8d9d2057 ee39cdc5
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -2008,11 +2008,26 @@ public:
              dev->SetConnectionState(DeviceConnectState::DISCONNECTED);
            }
          }

          /* If group is Streaming or is in transition for Streaming - lets stop it
           * and mark device to disconnect when stream is closed
           */
          if (group->IsStreaming() || !group->IsReleasingOrIdle()) {
            log::debug("group_id {} needs to stop streaming before {} disconnection",
                       group->group_id_, leAudioDevice->address_);
            leAudioDevice->closing_stream_for_disconnection_ = true;
            groupStateMachine_->StopStream(group);
            return;
          }

          if (group->IsReleasing()) {
            log::debug("group_id {} needs to stop streaming before {} disconnection",
                       group->group_id_, leAudioDevice->address_);
            /* Stream is releasing, wait till it is completed and then disconnect ACL. */
            leAudioDevice->closing_stream_for_disconnection_ = true;
            return;
          }

          force_acl_disconnect &= group->IsEnabled();
        }

+4 −0
Original line number Diff line number Diff line
@@ -1138,6 +1138,10 @@ bool LeAudioDeviceGroup::IsReleasingOrIdle(void) const {
          !in_transition_);
}

bool LeAudioDeviceGroup::IsReleasing(void) const {
  return (target_state_ == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) && in_transition_;
}

bool LeAudioDeviceGroup::IsGroupStreamReady(void) const {
  bool is_device_ready = false;

+1 −0
Original line number Diff line number Diff line
@@ -407,6 +407,7 @@ public:
  }
  bool IsStreaming(void) const;
  bool IsReleasingOrIdle(void) const;
  bool IsReleasing(void) const;

  void PrintDebugState(void) const;
  void Dump(std::stringstream& stream, int active_group_id) const;
+72 −1
Original line number Diff line number Diff line
@@ -492,6 +492,12 @@ protected:
            base::Unretained(this->gatt_callback), event_data));
  }
  void TriggerDisconnectionFromApp(const RawAddress& address) {
    do_in_main_thread(base::BindOnce(
            [](LeAudioClient* client, const RawAddress& address) { client->Disconnect(address); },
            LeAudioClient::Get(), address));
  }
  void InjectDisconnectedEvent(uint16_t conn_id,
                               tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
    ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
@@ -1434,9 +1440,15 @@ protected:
      // Inject the state
      group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
      group->SetState(group->GetTargetState());
      group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
      state_machine_callbacks_->StatusReportCb(group->group_id_, GroupStreamStatus::RELEASING);
      if (stay_at_releasing_stop_stream) {
        log::info("StopStream {} -> stay in Releasing state", group->group_id_);
        return;
      }
      group->SetState(group->GetTargetState());
      do_in_main_thread(base::BindOnce(
              [](bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* cb, int group_id) {
                cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
@@ -1477,6 +1489,7 @@ protected:
    SetUpMockCodecManager(codec_location);
    stay_at_qos_config_in_start_stream = false;
    stay_at_releasing_stop_stream = false;
    available_snk_context_types_ = 0xffff;
    available_src_context_types_ = 0xffff;
@@ -2699,6 +2712,7 @@ protected:
  bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_;
  std::map<int, LeAudioDeviceGroup*> streaming_groups;
  bool stay_at_qos_config_in_start_stream = false;
  bool stay_at_releasing_stop_stream = false;
  bool attach_to_stream_scheduled = false;
@@ -6056,6 +6070,63 @@ TEST_F(UnicastTest, DisconnecteWhileAlmostStreaming) {
  ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
}
TEST_F(UnicastTest, DisconnecteWhileAlmostStreaming_twoDevices) {
  const RawAddress test_address0 = GetTestAddress(0);
  const RawAddress test_address1 = GetTestAddress(1);
  int group_id = 5;
  TestSetupRemoteDevices(group_id);
  SyncOnMainLoop();
  EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
  StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
  Mock::VerifyAndClearExpectations(&mock_state_machine_);
  SyncOnMainLoop();
  ASSERT_NE(0lu, streaming_groups.count(group_id));
  auto group_inject = streaming_groups.at(group_id);
  // This shall be called once only when first device from the group is disconnecting.
  EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
  EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::DISCONNECTED, _))
          .Times(0);
  // Do not got to IDLE state imidiatelly.
  stay_at_releasing_stop_stream = true;
  log::info("First of all disconnect: {}", test_address0);
  TriggerDisconnectionFromApp(test_address0);
  SyncOnMainLoop();
  log::info("Secondly disconnect: {}", test_address1);
  TriggerDisconnectionFromApp(test_address1);
  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_state_machine_);
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  EXPECT_CALL(mock_audio_hal_client_callbacks_,
              OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
          .Times(1);
  EXPECT_CALL(mock_audio_hal_client_callbacks_,
              OnConnectionState(ConnectionState::DISCONNECTED, test_address1))
          .Times(1);
  do_in_main_thread(base::BindOnce(
          [](bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* cb, int group_id) {
            cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
          },
          state_machine_callbacks_, group_id));
  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
}
TEST_F(UnicastTest, EarbudsTwsStyleStreaming) {
  const RawAddress test_address0 = GetTestAddress(0);
  int group_id = bluetooth::groups::kGroupUnknown;