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

Commit 7a3e85c7 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Add timeout to VBC close

Once the Voiceback channel is closed (recording is suspended)
we usually reconfigure to a different configuration on the next
playback track metadata update. This change adds an additional
trigger if no playback track metadata is updated after the
recording has finished. This is just to prepare for a more common
MEDIA playback scenario before any playback event happens, which
should reduce the initial configuration time in most common
use cases.

Bug: 256967923
Test: manual testing
Change-Id: I1b09f805c06eb918d03b4bf67a3d26fcb0513569
parent b50cf10a
Loading
Loading
Loading
Loading
+64 −1
Original line number Diff line number Diff line
@@ -217,8 +217,9 @@ DeviceGroupsCallbacks* device_group_callbacks;
class LeAudioClientImpl : public LeAudioClient {
 public:
  ~LeAudioClientImpl() {
    alarm_free(close_vbc_timeout_);
    alarm_free(disable_timer_);
    alarm_free(suspend_timeout_);
    suspend_timeout_ = nullptr;
  };

  LeAudioClientImpl(
@@ -246,6 +247,7 @@ class LeAudioClientImpl : public LeAudioClient {
        lc3_decoder_right(nullptr),
        le_audio_source_hal_client_(nullptr),
        le_audio_sink_hal_client_(nullptr),
        close_vbc_timeout_(alarm_new("LeAudioCloseVbcTimeout")),
        suspend_timeout_(alarm_new("LeAudioSuspendTimeout")),
        disable_timer_(alarm_new("LeAudioDisableTimer")) {
    LeAudioGroupStateMachine::Initialize(state_machine_callbacks_);
@@ -269,6 +271,56 @@ class LeAudioClientImpl : public LeAudioClient {
    DeviceGroups::Get()->Initialize(device_group_callbacks);
  }

  void ReconfigureAfterVbcClose() {
    LOG_DEBUG("VBC close timeout");

    auto group = aseGroups_.FindById(active_group_id_);
    if (!group) {
      LOG_ERROR("Invalid group: %d", active_group_id_);
      return;
    }

    /* Test the existing metadata against the recent availability */
    metadata_context_types_.sink &= group->GetAvailableContexts();
    if (metadata_context_types_.sink.none()) {
      LOG_WARN("invalid/unknown context metadata, using 'MEDIA' instead");
      metadata_context_types_.sink = AudioContexts(LeAudioContextType::MEDIA);
    }

    /* Choose the right configuration context */
    auto new_configuration_context =
        ChooseConfigurationContextType(metadata_context_types_.sink);

    LOG_DEBUG("new_configuration_context= %s",
              ToString(new_configuration_context).c_str());
    ReconfigureOrUpdateMetadata(group, new_configuration_context,
                                metadata_context_types_.sink);
  }

  void StartVbcCloseTimeout() {
    if (alarm_is_scheduled(close_vbc_timeout_)) {
      StopVbcCloseTimeout();
    }

    static const uint64_t timeoutMs = 2000;
    LOG_DEBUG("Start VBC close timeout with %lu ms",
              static_cast<unsigned long>(timeoutMs));

    alarm_set_on_mloop(
        close_vbc_timeout_, timeoutMs,
        [](void*) {
          if (instance) instance->ReconfigureAfterVbcClose();
        },
        nullptr);
  }

  void StopVbcCloseTimeout() {
    if (alarm_is_scheduled(close_vbc_timeout_)) {
      LOG_DEBUG("Cancel VBC close timeout");
      alarm_cancel(close_vbc_timeout_);
    }
  }

  void AseInitialStateReadRequest(LeAudioDevice* leAudioDevice) {
    int ases_num = leAudioDevice->ases_.size();
    void* notify_flag_ptr = NULL;
@@ -2953,6 +3005,7 @@ class LeAudioClientImpl : public LeAudioClient {
  }

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

    if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
@@ -3239,6 +3292,8 @@ class LeAudioClientImpl : public LeAudioClient {
             ToString(audio_receiver_state_).c_str(),
             ToString(audio_sender_state_).c_str());

    StartVbcCloseTimeout();

    /* Note: This callback is from audio hal driver.
     * Bluetooth peer is a Source for Audio Framework.
     * e.g. Peer is microphone.
@@ -3281,6 +3336,8 @@ class LeAudioClientImpl : public LeAudioClient {
    LOG_INFO("IN: audio_receiver_state_: %s,  audio_sender_state_: %s",
             ToString(audio_receiver_state_).c_str(),
             ToString(audio_sender_state_).c_str());
    /* Stop the VBC close watchdog if needed */
    StopVbcCloseTimeout();

    /* Note: This callback is from audio hal driver.
     * Bluetooth peer is a Source for Audio Framework.
@@ -3499,6 +3556,11 @@ class LeAudioClientImpl : public LeAudioClient {
      return;
    }

    /* Stop the VBC close timeout timer, since we will reconfigure anyway if the
     * VBC was suspended.
     */
    StopVbcCloseTimeout();

    LOG_DEBUG("group state=%s, target_state=%s",
              ToString(group->GetState()).c_str(),
              ToString(group->GetTargetState()).c_str());
@@ -4194,6 +4256,7 @@ class LeAudioClientImpl : public LeAudioClient {
  static constexpr uint64_t kAudioDisableTimeoutMs = 3000;
  static constexpr char kAudioSuspentKeepIsoAliveTimeoutMsProp[] =
      "persist.bluetooth.leaudio.audio.suspend.timeoutms";
  alarm_t* close_vbc_timeout_;
  alarm_t* suspend_timeout_;
  alarm_t* disable_timer_;
  static constexpr uint64_t kDeviceAttachDelayMs = 500;