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

Commit a04f7fa9 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Use direction aware audio contexts on enable and metadata update

Passing sink and source audio contexts to the state machine as one
value is usually fine, but at the moment ASEs are enabled or metadata
is updated we should filter this combined value by the directional context
availability. For a mixed audio contexts this will prevent situations where
MEDIA context is used to enable remote audio source ASE (microphone).

Bug: 256967923
Tag: #feature
Test: atest --host bluetooth_le_audio_test bluetooth_le_audio_client_test --no-bazel-mode
Change-Id: I675aa85ef5d3ed62703f5d5ce6e7d2d1083cf015
Merged-In: I675aa85ef5d3ed62703f5d5ce6e7d2d1083cf015
(cherry picked from commit 7a4e787f)
parent 9d9e33c3
Loading
Loading
Loading
Loading
+29 −13
Original line number Diff line number Diff line
@@ -1521,7 +1521,16 @@ bool LeAudioDevice::ConfigureAses(
    ase->retrans_nb = ent.qos.retransmission_number;
    ase->max_transport_latency = ent.qos.max_transport_latency;

    ase->metadata = GetMetadata(metadata_context_type, ccid_list);
    /* Filter multidirectional audio context for each ase direction */
    auto directional_audio_context =
        metadata_context_type & GetAvailableContexts(ase->direction);
    if (directional_audio_context.any()) {
      ase->metadata = GetMetadata(directional_audio_context, ccid_list);
    } else {
      ase->metadata =
          GetMetadata(AudioContexts(LeAudioContextType::UNSPECIFIED),
                      std::vector<uint8_t>());
    }

    DLOG(INFO) << __func__ << " device=" << address_
               << ", activated ASE id=" << +ase->id
@@ -2403,8 +2412,8 @@ uint8_t LeAudioDevice::GetPhyBitmask(void) {

void LeAudioDevice::SetSupportedContexts(AudioContexts snk_contexts,
                                         AudioContexts src_contexts) {
  supp_snk_context_ = snk_contexts;
  supp_src_context_ = src_contexts;
  supp_contexts_.sink = snk_contexts;
  supp_contexts_.source = src_contexts;
}

void LeAudioDevice::Dump(int fd) {
@@ -2446,8 +2455,14 @@ void LeAudioDevice::DisconnectAcl(void) {
  }
}

AudioContexts LeAudioDevice::GetAvailableContexts(void) {
  return avail_snk_contexts_ | avail_src_contexts_;
types::AudioContexts LeAudioDevice::GetAvailableContexts(int direction) {
  if (direction ==
      (types::kLeAudioDirectionSink | types::kLeAudioDirectionSource)) {
    return get_bidirectional(avail_contexts_);
  } else if (direction == types::kLeAudioDirectionSink) {
    return avail_contexts_.sink;
  }
  return avail_contexts_.source;
}

/* Returns XOR of updated sink and source bitset context types */
@@ -2455,18 +2470,19 @@ AudioContexts LeAudioDevice::SetAvailableContexts(AudioContexts snk_contexts,
                                                  AudioContexts src_contexts) {
  AudioContexts updated_contexts;

  updated_contexts = snk_contexts ^ avail_snk_contexts_;
  updated_contexts |= src_contexts ^ avail_src_contexts_;
  updated_contexts = snk_contexts ^ avail_contexts_.sink;
  updated_contexts |= src_contexts ^ avail_contexts_.source;

  LOG_DEBUG(
      "\n\t avail_snk_contexts_: %s \n\t avail_src_contexts_: %s  \n\t "
      "\n\t avail_contexts_.sink: %s \n\t avail_contexts_.source: %s  \n\t "
      "snk_contexts: %s \n\t src_contexts: %s \n\t updated_contexts: %s",
      avail_snk_contexts_.to_string().c_str(),
      avail_src_contexts_.to_string().c_str(), snk_contexts.to_string().c_str(),
      src_contexts.to_string().c_str(), updated_contexts.to_string().c_str());
      avail_contexts_.sink.to_string().c_str(),
      avail_contexts_.source.to_string().c_str(),
      snk_contexts.to_string().c_str(), src_contexts.to_string().c_str(),
      updated_contexts.to_string().c_str());

  avail_snk_contexts_ = snk_contexts;
  avail_src_contexts_ = src_contexts;
  avail_contexts_.sink = snk_contexts;
  avail_contexts_.source = src_contexts;

  return updated_contexts;
}
+5 −5
Original line number Diff line number Diff line
@@ -168,7 +168,9 @@ class LeAudioDevice {
                     const std::vector<uint8_t>& ccid_list);
  void SetSupportedContexts(types::AudioContexts snk_contexts,
                            types::AudioContexts src_contexts);
  types::AudioContexts GetAvailableContexts(void);
  types::AudioContexts GetAvailableContexts(
      int direction = (types::kLeAudioDirectionSink |
                       types::kLeAudioDirectionSource));
  types::AudioContexts SetAvailableContexts(types::AudioContexts snk_cont_val,
                                            types::AudioContexts src_cont_val);
  void DeactivateAllAses(void);
@@ -181,10 +183,8 @@ class LeAudioDevice {
                         const std::vector<uint8_t>& ccid_list);

 private:
  types::AudioContexts avail_snk_contexts_;
  types::AudioContexts avail_src_contexts_;
  types::AudioContexts supp_snk_context_;
  types::AudioContexts supp_src_context_;
  types::BidirectionalPair<types::AudioContexts> avail_contexts_;
  types::BidirectionalPair<types::AudioContexts> supp_contexts_;
};

/* LeAudioDevices class represents a wraper helper over all devices in le audio
+5 −0
Original line number Diff line number Diff line
@@ -410,6 +410,7 @@ class AudioContexts {
  bool operator==(const AudioContexts& other) const {
    return value() == other.value();
  };
  constexpr AudioContexts operator~() const { return AudioContexts(~value()); }
};

AudioContexts operator|(std::underlying_type<LeAudioContextType>::type lhs,
@@ -425,6 +426,10 @@ constexpr AudioContexts operator|(const AudioContexts& lhs,
                                  const AudioContexts& rhs) {
  return AudioContexts(lhs.value() | rhs.value());
}
constexpr AudioContexts operator&(const AudioContexts& lhs,
                                  const AudioContexts& rhs) {
  return AudioContexts(lhs.value() & rhs.value());
}
constexpr AudioContexts operator|(const LeAudioContextType& lhs,
                                  const LeAudioContextType& rhs) {
  using T = std::underlying_type<LeAudioContextType>::type;
+14 −3
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ using le_audio::types::AudioContexts;
using le_audio::types::AudioStreamDataPathState;
using le_audio::types::CigState;
using le_audio::types::CodecLocation;
using le_audio::types::LeAudioContextType;

namespace {

@@ -2024,8 +2025,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
         leAudioDevice = group->GetNextActiveDevice(leAudioDevice)) {
      if (!leAudioDevice->IsMetadataChanged(context_type, ccid_list)) continue;

      auto new_metadata = leAudioDevice->GetMetadata(context_type, ccid_list);

      /* Request server to update ASEs with new metadata */
      for (struct ase* ase = leAudioDevice->GetFirstActiveAse(); ase != nullptr;
           ase = leAudioDevice->GetNextActiveAse(ase)) {
@@ -2033,10 +2032,22 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
                  leAudioDevice->address_.ToString().c_str(), ase->id,
                  ase->cis_id, ToString(ase->state).c_str());

        /* Filter multidirectional audio context for each ase direction */
        auto directional_audio_context =
            context_type & leAudioDevice->GetAvailableContexts(ase->direction);
        if (directional_audio_context.any()) {
          ase->metadata =
              leAudioDevice->GetMetadata(directional_audio_context, ccid_list);
        } else {
          ase->metadata = leAudioDevice->GetMetadata(
              AudioContexts(LeAudioContextType::UNSPECIFIED),
              std::vector<uint8_t>());
        }

        struct le_audio::client_parser::ascs::ctp_update_metadata conf;

        conf.ase_id = ase->id;
        conf.metadata = new_metadata;
        conf.metadata = ase->metadata;

        confs.push_back(conf);
      }