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

Commit 760f3c14 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Alice Kuo
Browse files

leaudio: Improve cleanup on Bluetooth stack off

Cleanup() is called when Bluetooth stack is off via GUI.
However, Bluetooth chip still might work for other purposes.
Therefore on Cleanup we make sure that all CISes and ACLs are
disconnected.
Note: In case of Bluetooth being Off while, streaming, we might end up
with a CIG created in the controller. It will be cleared on Bluetooth On
event, as HCI Reset is sent to the controller.

Bug: 150670922
Test: atest bluetooth_le_audio_client_test
Change-Id: Ia5ad66b0949ed693499efc88de7ffc783508a4c3
Merged-In: Ia5ad66b0949ed693499efc88de7ffc783508a4c3
(cherry picked from commit ab4a7d4b)
parent 06f7bd00
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -2559,10 +2559,15 @@ class LeAudioClientImpl : public LeAudioClient {

  void Cleanup(base::Callback<void()> cleanupCb) {
    if (alarm_is_scheduled(suspend_timeout_)) alarm_cancel(suspend_timeout_);

    if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
      /* Bluetooth turned off while streaming */
      StopAudio();
      ClientAudioIntefraceRelease();
    }
    groupStateMachine_->Cleanup();
    leAudioDevices_.Cleanup();
    aseGroups_.Cleanup();
    StopAudio();
    leAudioDevices_.Cleanup();
    if (gatt_if_) BTA_GATTC_AppDeregister(gatt_if_);

    std::move(cleanupCb).Run();
+42 −2
Original line number Diff line number Diff line
@@ -102,7 +102,42 @@ int LeAudioDeviceGroup::NumOfConnected(types::LeAudioContextType context_type) {
      });
}

void LeAudioDeviceGroup::Cleanup(void) { leAudioDevices_.clear(); }
void LeAudioDeviceGroup::Cleanup(void) {
  /* Bluetooth is off while streaming - disconnect CISes and remove CIG */
  if (GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
    if (!stream_conf.sink_streams.empty()) {
      for (auto [cis_handle, audio_location] : stream_conf.sink_streams) {
        bluetooth::hci::IsoManager::GetInstance()->DisconnectCis(
            cis_handle, HCI_ERR_PEER_USER);

        if (stream_conf.source_streams.empty()) {
          continue;
        }
        uint16_t cis_hdl = cis_handle;
        stream_conf.source_streams.erase(
            std::remove_if(
                stream_conf.source_streams.begin(),
                stream_conf.source_streams.end(),
                [cis_hdl](auto& pair) { return pair.first == cis_hdl; }),
            stream_conf.source_streams.end());
      }
    }

    if (!stream_conf.source_streams.empty()) {
      for (auto [cis_handle, audio_location] : stream_conf.source_streams) {
        bluetooth::hci::IsoManager::GetInstance()->DisconnectCis(
            cis_handle, HCI_ERR_PEER_USER);
      }
    }
  }

  /* Note: CIG will stay in the controller. We cannot remove it here, because
   * Cises are not yet disconnected.
   * When user start Bluetooth, HCI Reset should remove it
   */

  leAudioDevices_.clear();
}

void LeAudioDeviceGroup::Deactivate(void) {
  for (auto* leAudioDevice = GetFirstActiveDevice(); leAudioDevice;
@@ -1900,6 +1935,11 @@ void LeAudioDevices::Dump(int fd, int group_id) {
  }
}

void LeAudioDevices::Cleanup(void) { leAudioDevices_.clear(); }
void LeAudioDevices::Cleanup(void) {
  for (auto const& device : leAudioDevices_) {
    device->DisconnectAcl();
  }
  leAudioDevices_.clear();
}

}  // namespace le_audio