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

Commit 615f26a8 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski Committed by Łukasz Rymanowski
Browse files

LeAudio: Improve BidirectionalPair type

 - Changed get() to follow the common idiom, while copy constructor
will be called anyway if non-reference type is on the left hand side
of the assignment. There is no need for explicit reference getter.

 - It no longer requires comparison operators, which may no be defined
for the more complex types.

 - For the more complex types a single bidirectional value cannot be
 computed (e.g. a bidirectional pair of ASEs).

This allows us to wrap more complex types and simplify the code further.

Bug: 295972694
Test: atest bluetooth_le_audio_test bluetooth_le_audio_client_test  bluetooth_test_broadcaster bluetooth_test_broadcaster_state_machine
Change-Id: I35518479075732d8aa87082dd9267864161f43b3
parent 5558bf9b
Loading
Loading
Loading
Loading
+14 −14
Original line number Original line Diff line number Diff line
@@ -4352,7 +4352,7 @@ class LeAudioClientImpl : public LeAudioClient {
          "invalid/unknown %s context metadata, using 'UNSPECIFIED' instead",
          "invalid/unknown %s context metadata, using 'UNSPECIFIED' instead",
          (remote_dir == le_audio::types::kLeAudioDirectionSink) ? "sink"
          (remote_dir == le_audio::types::kLeAudioDirectionSink) ? "sink"
                                                                 : "source");
                                                                 : "source");
      contexts_pair.get_ref(remote_dir) =
      contexts_pair.get(remote_dir) =
          AudioContexts(LeAudioContextType::UNSPECIFIED);
          AudioContexts(LeAudioContextType::UNSPECIFIED);
    }
    }


@@ -4380,13 +4380,13 @@ class LeAudioClientImpl : public LeAudioClient {
      }
      }


      LOG_DEBUG("Checking contexts: %s, against the available contexts: %s",
      LOG_DEBUG("Checking contexts: %s, against the available contexts: %s",
                ToString(contexts_pair.get_ref(dir)).c_str(),
                ToString(contexts_pair.get(dir)).c_str(),
                ToString(group_available_contexts).c_str());
                ToString(group_available_contexts).c_str());
      auto unavail_contexts =
      auto unavail_contexts =
          contexts_pair.get_ref(dir) & ~group_available_contexts;
          contexts_pair.get(dir) & ~group_available_contexts;
      if (unavail_contexts.none()) continue;
      if (unavail_contexts.none()) continue;


      contexts_pair.get_ref(dir) &= group_available_contexts;
      contexts_pair.get(dir) &= group_available_contexts;
      auto unavail_but_supported =
      auto unavail_but_supported =
          (unavail_contexts & group->GetSupportedContexts(dir));
          (unavail_contexts & group->GetSupportedContexts(dir));
      if (unavail_but_supported.none() &&
      if (unavail_but_supported.none() &&
@@ -4396,7 +4396,7 @@ class LeAudioClientImpl : public LeAudioClient {
        /* All unavailable are also unsupported - replace with UNSPECIFIED if
        /* All unavailable are also unsupported - replace with UNSPECIFIED if
         * available
         * available
         */
         */
        contexts_pair.get_ref(dir).set(LeAudioContextType::UNSPECIFIED);
        contexts_pair.get(dir).set(LeAudioContextType::UNSPECIFIED);
      } else {
      } else {
        LOG_DEBUG("Some contexts are supported but currently unavailable: %s!",
        LOG_DEBUG("Some contexts are supported but currently unavailable: %s!",
                  ToString(unavail_but_supported).c_str());
                  ToString(unavail_but_supported).c_str());
@@ -4432,12 +4432,12 @@ class LeAudioClientImpl : public LeAudioClient {
                "Other direction is streaming. Aligning other direction"
                "Other direction is streaming. Aligning other direction"
                " metadata to match the current direciton context: %s",
                " metadata to match the current direciton context: %s",
                ToString(contexts_pair.get(other_dir)).c_str());
                ToString(contexts_pair.get(other_dir)).c_str());
            contexts_pair.get_ref(dir) = contexts_pair.get(other_dir);
            contexts_pair.get(dir) = contexts_pair.get(other_dir);
          }
          }
        } else {
        } else {
          LOG_DEBUG("Removing UNSPECIFIED from the remote sink context: %s",
          LOG_DEBUG("Removing UNSPECIFIED from the remote sink context: %s",
                    ToString(contexts_pair.get(other_dir)).c_str());
                    ToString(contexts_pair.get(other_dir)).c_str());
          contexts_pair.get_ref(dir).unset(LeAudioContextType::UNSPECIFIED);
          contexts_pair.get(dir).unset(LeAudioContextType::UNSPECIFIED);
        }
        }
      }
      }
    }
    }
@@ -4573,7 +4573,7 @@ class LeAudioClientImpl : public LeAudioClient {
      LOG_DEBUG(
      LOG_DEBUG(
          "The other direction is not streaming bidirectional, ignore that "
          "The other direction is not streaming bidirectional, ignore that "
          "context.");
          "context.");
      remote_metadata.get_ref(remote_other_direction).clear();
      remote_metadata.get(remote_other_direction).clear();
    }
    }


    /* Mixed contexts in the voiceback channel scenarios can confuse the remote
    /* Mixed contexts in the voiceback channel scenarios can confuse the remote
@@ -4587,13 +4587,13 @@ class LeAudioClientImpl : public LeAudioClient {
          "context");
          "context");
      if (!is_streaming_other_direction) {
      if (!is_streaming_other_direction) {
        // Do not take the obsolete metadata
        // Do not take the obsolete metadata
        remote_metadata.get_ref(remote_other_direction).clear();
        remote_metadata.get(remote_other_direction).clear();
      }
      }
      remote_metadata.get_ref(remote_other_direction)
      remote_metadata.get(remote_other_direction)
          .unset_all(kLeAudioContextAllBidir);
          .unset_all(kLeAudioContextAllBidir);
      remote_metadata.get_ref(remote_other_direction)
      remote_metadata.get(remote_other_direction)
          .unset_all(kLeAudioContextAllRemoteSinkOnly);
          .unset_all(kLeAudioContextAllRemoteSinkOnly);
      remote_metadata.get_ref(remote_other_direction)
      remote_metadata.get(remote_other_direction)
          .set_all(remote_metadata.get(remote_direction) &
          .set_all(remote_metadata.get(remote_direction) &
                   ~kLeAudioContextAllRemoteSinkOnly);
                   ~kLeAudioContextAllRemoteSinkOnly);
    }
    }
@@ -4618,9 +4618,9 @@ class LeAudioClientImpl : public LeAudioClient {
        /* Turn off bidirectional contexts on this direction to avoid mixing
        /* Turn off bidirectional contexts on this direction to avoid mixing
         * with the other direction bidirectional context
         * with the other direction bidirectional context
         */
         */
        remote_metadata.get_ref(remote_direction)
        remote_metadata.get(remote_direction)
            .unset_all(kLeAudioContextAllBidir);
            .unset_all(kLeAudioContextAllBidir);
        remote_metadata.get_ref(remote_direction)
        remote_metadata.get(remote_direction)
            .set_all(remote_metadata.get(remote_other_direction));
            .set_all(remote_metadata.get(remote_other_direction));
      }
      }
    }
    }
+1 −1
Original line number Original line Diff line number Diff line
@@ -1604,7 +1604,7 @@ bool LeAudioDevice::ConfigureAses(
      /*Let's choose audio channel allocation if not set */
      /*Let's choose audio channel allocation if not set */
      ase->codec_config.audio_channel_allocation =
      ase->codec_config.audio_channel_allocation =
          PickAudioLocation(strategy, audio_locations,
          PickAudioLocation(strategy, audio_locations,
                            group_audio_locations_memo.get_ref(ent.direction));
                            group_audio_locations_memo.get(ent.direction));


      /* Get default value if no requirement for specific frame blocks per sdu
      /* Get default value if no requirement for specific frame blocks per sdu
       */
       */
+32 −18
Original line number Original line Diff line number Diff line
@@ -186,9 +186,14 @@ class LeAudioDevice {
      bool reuse_cis_id);
      bool reuse_cis_id);


  inline types::AudioContexts GetSupportedContexts(
  inline types::AudioContexts GetSupportedContexts(
      int direction = (types::kLeAudioDirectionSink |
      int direction = types::kLeAudioDirectionBoth) const {
                       types::kLeAudioDirectionSource)) const {
    ASSERT_LOG(direction <= (types::kLeAudioDirectionBoth),
               "Invalid direction used.");

    if (direction < types::kLeAudioDirectionBoth)
      return supp_contexts_.get(direction);
      return supp_contexts_.get(direction);
    else
      return types::get_bidirectional(supp_contexts_);
  }
  }
  inline void SetSupportedContexts(
  inline void SetSupportedContexts(
      types::BidirectionalPair<types::AudioContexts> contexts) {
      types::BidirectionalPair<types::AudioContexts> contexts) {
@@ -196,9 +201,14 @@ class LeAudioDevice {
  }
  }


  inline types::AudioContexts GetAvailableContexts(
  inline types::AudioContexts GetAvailableContexts(
      int direction = (types::kLeAudioDirectionSink |
      int direction = types::kLeAudioDirectionBoth) const {
                       types::kLeAudioDirectionSource)) const {
    ASSERT_LOG(direction <= (types::kLeAudioDirectionBoth),
               "Invalid direction used.");

    if (direction < types::kLeAudioDirectionBoth)
      return avail_contexts_.get(direction);
      return avail_contexts_.get(direction);
    else
      return types::get_bidirectional(avail_contexts_);
  }
  }
  void SetAvailableContexts(
  void SetAvailableContexts(
      types::BidirectionalPair<types::AudioContexts> cont_val);
      types::BidirectionalPair<types::AudioContexts> cont_val);
@@ -475,9 +485,11 @@ class LeAudioDeviceGroup {
        group_available_contexts_.source.to_string().c_str());
        group_available_contexts_.source.to_string().c_str());
  }
  }


  inline types::AudioContexts GetAvailableContexts(
  types::AudioContexts GetAvailableContexts(
      int direction = (types::kLeAudioDirectionSink |
      int direction = types::kLeAudioDirectionBoth) const {
                       types::kLeAudioDirectionSource)) const {
    ASSERT_LOG(direction <= (types::kLeAudioDirectionBoth),
               "Invalid direction used.");
    if (direction < types::kLeAudioDirectionBoth) {
      LOG_DEBUG(
      LOG_DEBUG(
          " group id: %d, available contexts sink: %s, available contexts "
          " group id: %d, available contexts sink: %s, available contexts "
          "source: "
          "source: "
@@ -485,11 +497,13 @@ class LeAudioDeviceGroup {
          group_id_, group_available_contexts_.sink.to_string().c_str(),
          group_id_, group_available_contexts_.sink.to_string().c_str(),
          group_available_contexts_.source.to_string().c_str());
          group_available_contexts_.source.to_string().c_str());
      return group_available_contexts_.get(direction);
      return group_available_contexts_.get(direction);
    } else {
      return types::get_bidirectional(group_available_contexts_);
    }
  }
  }


  types::AudioContexts GetSupportedContexts(
  types::AudioContexts GetSupportedContexts(
      int direction = (types::kLeAudioDirectionSink |
      int direction = types::kLeAudioDirectionBoth) const;
                       types::kLeAudioDirectionSource)) const;


  types::BidirectionalPair<types::AudioContexts> GetLatestAvailableContexts(
  types::BidirectionalPair<types::AudioContexts> GetLatestAvailableContexts(
      void) const;
      void) const;
+17 −0
Original line number Original line Diff line number Diff line
@@ -907,6 +907,23 @@ std::ostream& operator<<(std::ostream& os, const AudioContexts& contexts) {
  return os;
  return os;
}
}


template <typename T>
const T& BidirectionalPair<T>::get(uint8_t direction) const {
  ASSERT_LOG(
      direction < types::kLeAudioDirectionBoth,
      "Unsupported complex direction. Consider using get_bidirectional<>() "
      "instead.");
  return (direction == types::kLeAudioDirectionSink) ? sink : source;
}

template <typename T>
T& BidirectionalPair<T>::get(uint8_t direction) {
  ASSERT_LOG(direction < types::kLeAudioDirectionBoth,
             "Unsupported complex direction. Reference to a single complex"
             " direction value is not supported.");
  return (direction == types::kLeAudioDirectionSink) ? sink : source;
}

/* Bidirectional getter trait for AudioContexts bidirectional pair */
/* Bidirectional getter trait for AudioContexts bidirectional pair */
template <>
template <>
AudioContexts get_bidirectional(BidirectionalPair<AudioContexts> p) {
AudioContexts get_bidirectional(BidirectionalPair<AudioContexts> p) {
+10 −18
Original line number Original line Diff line number Diff line
@@ -312,6 +312,8 @@ constexpr uint8_t kDefaultCsisSetSize = 2;


constexpr uint8_t kLeAudioDirectionSink = 0x01;
constexpr uint8_t kLeAudioDirectionSink = 0x01;
constexpr uint8_t kLeAudioDirectionSource = 0x02;
constexpr uint8_t kLeAudioDirectionSource = 0x02;
constexpr uint8_t kLeAudioDirectionBoth =
    kLeAudioDirectionSink | kLeAudioDirectionSource;


/* Audio stream config types */
/* Audio stream config types */
constexpr uint8_t kFramingUnframedPduSupported = 0x00;
constexpr uint8_t kFramingUnframedPduSupported = 0x00;
@@ -477,31 +479,21 @@ struct BidirectionalPair {
  T sink;
  T sink;
  T source;
  T source;


  T get(uint8_t direction) const {
  const T& get(uint8_t direction) const;
    if (direction ==
  T& get(uint8_t direction);
        (types::kLeAudioDirectionSink | types::kLeAudioDirectionSource)) {
      return get_bidirectional(*this);
    } else if (direction == types::kLeAudioDirectionSink) {
      return sink;
    }
    return source;
  }
  T& get_ref(uint8_t direction) {
    return (direction == types::kLeAudioDirectionSink) ? sink : source;
  }


  BidirectionalPair<T>& operator=(const BidirectionalPair<T>&) = default;
  BidirectionalPair<T>& operator=(const BidirectionalPair<T>&) = default;
  bool operator==(const BidirectionalPair<T>& other) const {
    return (sink == other.sink) && (source == other.source);
  };
  bool operator!=(const BidirectionalPair<T>& other) const {
    return (sink != other.sink) || (source != other.source);
  };
};
};


template <typename T>
template <typename T>
T get_bidirectional(BidirectionalPair<T> p);
T get_bidirectional(BidirectionalPair<T> p);


template <typename T>
bool operator==(const types::BidirectionalPair<T>& lhs,
                const types::BidirectionalPair<T>& rhs) {
  return (lhs.sink == rhs.sink) && (lhs.source == rhs.source);
}

/* Configuration strategy */
/* Configuration strategy */
enum class LeAudioConfigurationStrategy : uint8_t {
enum class LeAudioConfigurationStrategy : uint8_t {
  MONO_ONE_CIS_PER_DEVICE = 0x00, /* Common true wireless speakers */
  MONO_ONE_CIS_PER_DEVICE = 0x00, /* Common true wireless speakers */