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

Commit 03734fbd authored by Himanshu Rawat's avatar Himanshu Rawat
Browse files

Set datapath for the headtracking data

Set datapath for incoming headtracking data according to the DSA mode
selected.

Bug: 314844884
Bug: 309665975

Test: mmm packages/modules/Bluetooth
Test: Manual | LE Audio streaming with device supporting DSA
Change-Id: I0373b0c8af00ca8ed6fdf53a128aadb6aeecd6ab
parent 6652dbaf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4632,7 +4632,7 @@ class LeAudioClientImpl : public LeAudioClient {
        ToString(audio_receiver_state_).c_str(),
        ToString(audio_sender_state_).c_str());

    group->dsa_mode_ = dsa_mode;
    group->dsa_.mode = dsa_mode;

    /* Set the remote sink metadata context from the playback tracks metadata */
    local_metadata_context_types_.source =
+6 −2
Original line number Diff line number Diff line
@@ -84,7 +84,11 @@ class LeAudioDeviceGroup {
  /* Whether LE Audio is preferred for OUTPUT_ONLY and DUPLEX cases */
  bool is_output_preference_le_audio;
  bool is_duplex_preference_le_audio;
  DsaMode dsa_mode_;

  struct {
    DsaMode mode;
    bool active;
  } dsa_;
  bool asymmetric_phy_for_unidirectional_cis_supported;

  explicit LeAudioDeviceGroup(const int group_id)
@@ -93,7 +97,7 @@ class LeAudioDeviceGroup {
        stream_conf({}),
        notify_streaming_when_cises_are_ready_(false),
        audio_directions_(0),
        dsa_mode_(DsaMode::DISABLED),
        dsa_({DsaMode::DISABLED, false}),
        is_enabled_(true),
        transport_latency_mtos_us_(0),
        transport_latency_stom_us_(0),
+3 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ class LeAudioDevice {
        model_name_(""),
        allowlist_flag_(false),
        link_quality_timer(nullptr),
        dsa_state_(types::DataPathState::IDLE),
        dsa_modes_({DsaMode::DISABLED}) {}
  ~LeAudioDevice(void);

@@ -251,6 +252,8 @@ class LeAudioDevice {
  void UpdateDeviceAllowlistFlag(void);
  DsaModes GetDsaModes(void);

  types::DataPathState dsa_state_;

 private:
  types::BidirectionalPair<types::AudioContexts> avail_contexts_;
  types::BidirectionalPair<types::AudioContexts> supp_contexts_;
+105 −3
Original line number Diff line number Diff line
@@ -609,6 +609,17 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
      return;
    }

    if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
      if (group->dsa_.active &&
          (group->dsa_.mode == DsaMode::ISO_SW ||
           group->dsa_.mode == DsaMode::ISO_HW) &&
          leAudioDevice->dsa_state_ == DataPathState::CONFIGURING) {
        LOG_INFO("Datapath configured for headtracking");
        leAudioDevice->dsa_state_ = DataPathState::CONFIGURED;
        return;
      }
    }

    /* Update state for the given cis.*/
    auto ase = leAudioDevice->GetFirstActiveAseByCisAndDataPathState(
        CisState::CONNECTED, DataPathState::CONFIGURING);
@@ -686,6 +697,12 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        ases_pair.source->cis_state = CisState::DISCONNECTING;
        do_disconnect = true;
      }
    } else if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
      if (group->dsa_.active &&
          leAudioDevice->dsa_state_ == DataPathState::REMOVING) {
        LOG_INFO("DSA data path removed");
        leAudioDevice->dsa_state_ = DataPathState::IDLE;
      }
    }

    if (do_disconnect) {
@@ -847,6 +864,77 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
    }
  }

  void applyDsaDataPath(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
                        uint16_t conn_hdl) {
    if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
      return;
    }

    if (!group->dsa_.active) {
      LOG_INFO("DSA mode not used");
      return;
    }

    DsaModes dsa_modes = leAudioDevice->GetDsaModes();
    if (dsa_modes.empty()) {
      LOG_WARN("DSA mode not supported by this LE Audio device: %s",
               ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_));
      group->dsa_.active = false;
      return;
    }

    if (std::find(dsa_modes.begin(), dsa_modes.end(), DsaMode::ISO_SW) ==
            dsa_modes.end() &&
        std::find(dsa_modes.begin(), dsa_modes.end(), DsaMode::ISO_HW) ==
            dsa_modes.end()) {
      LOG_WARN("DSA mode not supported by this LE Audio device: %s",
               ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_));
      group->dsa_.active = false;
      return;
    }

    uint8_t data_path_id = bluetooth::hci::iso_manager::kIsoDataPathHci;
    LOG_INFO("DSA mode used: %d", static_cast<int>(group->dsa_.mode));
    switch (group->dsa_.mode) {
      case DsaMode::ISO_HW:
        data_path_id = bluetooth::hci::iso_manager::kIsoDataPathPlatformDefault;
        break;
      case DsaMode::ISO_SW:
        data_path_id = bluetooth::hci::iso_manager::kIsoDataPathHci;
        break;
      default:
        LOG_WARN("Unexpected DsaMode: %d", static_cast<int>(group->dsa_.mode));
        group->dsa_.active = false;
        return;
    }

    leAudioDevice->dsa_state_ = DataPathState::CONFIGURING;

    LOG_VERBOSE(
        "DSA mode supported on this LE Audio device: %s, apply data path: %d",
        ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), data_path_id);

    LeAudioLogHistory::Get()->AddLogHistory(
        kLogStateMachineTag, group->group_id_, RawAddress::kEmpty,
        kLogSetDataPathOp + "cis_h:" + loghex(conn_hdl),
        "direction: " +
            loghex(bluetooth::hci::iso_manager::kIsoDataPathDirectionOut));

    bluetooth::hci::iso_manager::iso_data_path_params param = {
        .data_path_dir = bluetooth::hci::iso_manager::kIsoDataPathDirectionOut,
        .data_path_id = data_path_id,
        .codec_id_format =
            le_audio::types::kLeAudioCodecHeadtracking.coding_format,
        .codec_id_company =
            le_audio::types::kLeAudioCodecHeadtracking.vendor_company_id,
        .codec_id_vendor =
            le_audio::types::kLeAudioCodecHeadtracking.vendor_codec_id,
        .controller_delay = 0x00000000,
        .codec_conf = std::vector<uint8_t>(),
    };
    IsoManager::GetInstance()->SetupIsoDataPath(conn_hdl, std::move(param));
  }

  void ProcessHciNotifCisEstablished(
      LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
      const bluetooth::hci::iso_manager::cis_establish_cmpl_evt* event)
@@ -923,6 +1011,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
    if (ases_pair.source &&
        (ases_pair.source->data_path_state == DataPathState::IDLE)) {
      PrepareDataPath(group->group_id_, ases_pair.source);
    } else {
      applyDsaDataPath(group, leAudioDevice, event->cis_conn_hdl);
    }

    if (osi_property_get_bool("persist.bluetooth.iso_link_quality_report",
@@ -996,6 +1086,14 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        ases_pair.source->data_path_state == DataPathState::CONFIGURED) {
      value |= bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput;
      ases_pair.source->data_path_state = DataPathState::REMOVING;
    } else {
      if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
        if (leAudioDevice->dsa_state_ == DataPathState::CONFIGURED) {
          value |=
              bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput;
          leAudioDevice->dsa_state_ = DataPathState::REMOVING;
        }
      }
    }

    if (value == 0) {
@@ -1320,13 +1418,14 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
      return;
    }

    LOG_INFO("DSA mode selected: %d", (int)group->dsa_mode_);
    LOG_INFO("DSA mode selected: %d", (int)group->dsa_.mode);
    group->dsa_.active = false;

    /* Unidirectional streaming */
    if (param.sdu_itv_stom == 0) {
      LOG_INFO("Media streaming, apply DSA parameters");

      switch (group->dsa_mode_) {
      switch (group->dsa_.mode) {
        case DsaMode::ISO_HW:
        case DsaMode::ISO_SW: {
          auto& cis_cfgs = param.cis_cfgs;
@@ -1335,9 +1434,12 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
          for (auto dsa_modes : group->GetAllowedDsaModesList()) {
            if (!dsa_modes.empty() && it != cis_cfgs.end()) {
              if (std::find(dsa_modes.begin(), dsa_modes.end(),
                            group->dsa_mode_) != dsa_modes.end()) {
                            group->dsa_.mode) != dsa_modes.end()) {
                LOG_INFO("Device found with support for selected DsaMode");

                group->dsa_.active = true;

                /* Todo: Replace literal values */
                param.sdu_itv_stom = 20000;
                param.max_trans_lat_stom = 10;
                it->max_sdu_size_stom = 15;