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

Commit 6efe37d2 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

leaudio: Improve disabling stream

With this patch, group state machine will send Disable command
simultaneously to all active devices.

Bug: 265501806
Test: atest bluetooth_le_audio_test
Test: atest BluetoothInstrumentationTests
Tag: #feature
Change-Id: Iaed6f7e6f93b93e459794f5e168ec3c907d5bc0f
parent 24d909eb
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -359,6 +359,18 @@ bool LeAudioDeviceGroup::IsGroupReadyToCreateStream(void) {
  return iter == leAudioDevices_.end();
}

bool LeAudioDeviceGroup::IsGroupReadyToSuspendStream(void) {
  auto iter =
      std::find_if(leAudioDevices_.begin(), leAudioDevices_.end(), [](auto& d) {
        if (d.expired())
          return false;
        else
          return !(((d.lock()).get())->IsReadyToSuspendStream());
      });

  return iter == leAudioDevices_.end();
}

bool LeAudioDeviceGroup::HaveAllActiveDevicesAsesTheSameState(AseState state) {
  auto iter = std::find_if(
      leAudioDevices_.begin(), leAudioDevices_.end(), [&state](auto& d) {
+1 −0
Original line number Diff line number Diff line
@@ -296,6 +296,7 @@ class LeAudioDeviceGroup {
  bool HaveAllActiveDevicesAsesTheSameState(types::AseState state);
  bool IsGroupStreamReady(void);
  bool IsGroupReadyToCreateStream(void);
  bool IsGroupReadyToSuspendStream(void);
  bool HaveAllCisesDisconnected(void);
  uint8_t GetFirstFreeCisId(void);
  uint8_t GetFirstFreeCisId(types::CisType cis_type);
+28 −16
Original line number Diff line number Diff line
@@ -269,15 +269,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
  }

  void SuspendStream(LeAudioDeviceGroup* group) override {
    LeAudioDevice* leAudioDevice = group->GetFirstActiveDevice();
    LOG_ASSERT(leAudioDevice)
        << __func__ << " Shouldn't be called without an active device.";

    /* All ASEs should aim to achieve target state */
    SetTargetState(group, AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
    PrepareAndSendDisable(leAudioDevice);
    state_machine_callbacks_->StatusReportCb(group->group_id_,
                                             GroupStreamStatus::SUSPENDING);
    auto status = PrepareAndSendDisableToTheGroup(group);
    state_machine_callbacks_->StatusReportCb(group->group_id_, status);
  }

  void StopStream(LeAudioDeviceGroup* group) override {
@@ -1952,7 +1947,7 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        /* Process the Disable Transition of the rest of group members if no
         * more ASE notifications has to come from this device. */
        if (leAudioDevice->IsReadyToSuspendStream())
          ProcessGroupDisable(group, leAudioDevice);
          ProcessGroupDisable(group);

        break;

@@ -2036,6 +2031,23 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
                                      GATT_WRITE_NO_RSP, NULL, NULL);
  }

  GroupStreamStatus PrepareAndSendDisableToTheGroup(LeAudioDeviceGroup* group) {
    LOG_INFO("grop_id: %d", group->group_id_);

    auto leAudioDevice = group->GetFirstActiveDevice();
    if (!leAudioDevice) {
      LOG_ERROR("Shall not be called if there is no active device.");
      StopStream(group);
      return GroupStreamStatus::IDLE;
    }

    for (; leAudioDevice;
         leAudioDevice = group->GetNextActiveDevice(leAudioDevice)) {
      PrepareAndSendDisable(leAudioDevice);
    }
    return GroupStreamStatus::SUSPENDING;
  }

  void PrepareAndSendDisable(LeAudioDevice* leAudioDevice) {
    ase* ase = leAudioDevice->GetFirstActiveAse();
    LOG_ASSERT(ase) << __func__ << " shouldn't be called without an active ASE";
@@ -2449,7 +2461,7 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        /* Process the Disable Transition of the rest of group members if no
         * more ASE notifications has to come from this device. */
        if (leAudioDevice->IsReadyToSuspendStream())
          ProcessGroupDisable(group, leAudioDevice);
          ProcessGroupDisable(group);

        break;

@@ -2579,13 +2591,15 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
    }
  }

  void ProcessGroupDisable(LeAudioDeviceGroup* group, LeAudioDevice* device) {
  void ProcessGroupDisable(LeAudioDeviceGroup* group) {
    /* Disable ASEs for next device in group. */
    LeAudioDevice* deviceNext = group->GetNextActiveDevice(device);
    if (deviceNext) {
      PrepareAndSendDisable(deviceNext);
    if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING) {
      if (!group->IsGroupReadyToSuspendStream()) {
        LOG_INFO("Waiting for all devices to be in disable state");
        return;
      }
      group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING);
    }

    /* At this point all of the active ASEs within group are disabled. As there
     * is no Disabling state for Sink ASE, it might happen that all of the
@@ -2594,8 +2608,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
    if (group->HaveAllActiveDevicesAsesTheSameState(
            AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED)) {
      group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
    } else {
      group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING);
    }

    /* Transition to QoS configured is done by CIS disconnection */