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

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

LeAudio: Remove boilerplate code around the context type usage

This eliminates the quirky static casts and type conversions making the
code around context types a bit more readable. By introducing stronger
types we can be sure if a particular part of the API expects a single
type or multiple context types. Previously there was to many ways of
passing multiple contexts: ORed enum class values (where the ored value
was not part of the enum value), integers, list of enums, raw bitsets,
and a type alias to bitset. It turned out the integer or bitset was
sometimes actually passing a single context. There could also be a case
where one parameter is passed as something completely different due to
compatible types. The explicit constructors should prevent any unwanted
conversions, while the additionall operators allows for clearly defined
type interactions.

Bug: 249737696
Tag: #refactor
Test: atest --host bluetooth_le_audio_test bluetooth_le_audio_client_test bluetooth_test_broadcaster bluetooth_test_broadcaster_state_machine  --no-bazel-mode
Change-Id: Ib4454b8c21e7bf4a2debcc5a1c37dc1526efa66f
Merged-In: Ib4454b8c21e7bf4a2debcc5a1c37dc1526efa66f
(cherry picked from commit 97f2d3a8)
parent ac5bdedd
Loading
Loading
Loading
Loading
+20 −33
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ using le_audio::broadcaster::BroadcastQosConfig;
using le_audio::broadcaster::BroadcastStateMachine;
using le_audio::broadcaster::BroadcastStateMachineConfig;
using le_audio::broadcaster::IBroadcastStateMachineCallbacks;
using le_audio::types::AudioContexts;
using le_audio::types::CodecLocation;
using le_audio::types::kLeAudioCodingFormatLC3;
using le_audio::types::LeAudioContextType;
@@ -167,18 +168,18 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    return announcement;
  }

  void UpdateStreamingContextTypeOnAllSubgroups(uint16_t context_type_map) {
    LOG_DEBUG("%s context_type_map=%d", __func__, context_type_map);
  void UpdateStreamingContextTypeOnAllSubgroups(const AudioContexts& contexts) {
    LOG_DEBUG("%s context_type_map=%s", __func__, contexts.to_string().c_str());

    auto ccids = GetAllCcids(context_type_map);
    auto ccids = GetAllCcids(contexts);
    if (ccids.empty()) {
      LOG_WARN("%s No content providers available for context_type_map=%d.",
               __func__, context_type_map);
      LOG_WARN("%s No content providers available for context_type_map=%s.",
               __func__, contexts.to_string().c_str());
    }

    std::vector<uint8_t> stream_context_vec(2);
    auto pp = stream_context_vec.data();
    UINT16_TO_STREAM(pp, context_type_map);
    UINT16_TO_STREAM(pp, contexts.value());

    for (auto const& kv_it : broadcasts_) {
      auto& broadcast = kv_it.second;
@@ -261,9 +262,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      return;
    }

    uint16_t context_type =
        static_cast<std::underlying_type<LeAudioContextType>::type>(
            LeAudioContextType::MEDIA);
    auto context_type = AudioContexts(LeAudioContextType::MEDIA);

    /* Adds multiple contexts and CCIDs regardless of the incoming audio
     * context. Android has only two CCIDs, one for Media and one for
@@ -273,15 +272,12 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    if (stack_config_get_interface()
            ->get_pts_force_le_audio_multiple_contexts_metadata()) {
      context_type =
          static_cast<std::underlying_type<LeAudioContextType>::type>(
              LeAudioContextType::MEDIA) |
          static_cast<std::underlying_type<LeAudioContextType>::type>(
              LeAudioContextType::CONVERSATIONAL);
          LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
      auto stream_context_vec =
          ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
      if (stream_context_vec) {
        auto pp = stream_context_vec.value().data();
        UINT16_TO_STREAM(pp, context_type);
        UINT16_TO_STREAM(pp, context_type.value());
      }
    }

@@ -289,7 +285,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
        ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
    if (stream_context_vec) {
      auto pp = stream_context_vec.value().data();
      STREAM_TO_UINT16(context_type, pp);
      STREAM_TO_UINT16(context_type.value_ref(), pp);
    }

    // Append the CCID list
@@ -321,9 +317,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      return;
    }

    uint16_t context_type =
        static_cast<std::underlying_type<LeAudioContextType>::type>(
            LeAudioContextType::MEDIA);
    auto context_type = AudioContexts(LeAudioContextType::MEDIA);

    /* Adds multiple contexts and CCIDs regardless of the incoming audio
     * context. Android has only two CCIDs, one for Media and one for
@@ -333,15 +327,12 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    if (stack_config_get_interface()
            ->get_pts_force_le_audio_multiple_contexts_metadata()) {
      context_type =
          static_cast<std::underlying_type<LeAudioContextType>::type>(
              LeAudioContextType::MEDIA) |
          static_cast<std::underlying_type<LeAudioContextType>::type>(
              LeAudioContextType::CONVERSATIONAL);
          LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
      auto stream_context_vec =
          ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
      if (stream_context_vec) {
        auto pp = stream_context_vec.value().data();
        UINT16_TO_STREAM(pp, context_type);
        UINT16_TO_STREAM(pp, context_type.value());
      }
    }

@@ -349,7 +340,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
        ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
    if (stream_context_vec) {
      auto pp = stream_context_vec.value().data();
      STREAM_TO_UINT16(context_type, pp);
      STREAM_TO_UINT16(context_type.value_ref(), pp);
    }

    // Append the CCID list
@@ -735,10 +726,8 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      : public LeAudioSourceAudioHalClient::Callbacks {
   public:
    LeAudioSourceCallbacksImpl()
        : codec_wrapper_(
              le_audio::broadcaster::getStreamConfigForContext(
                  static_cast<std::underlying_type<LeAudioContextType>::type>(
                      le_audio::types::LeAudioContextType::UNSPECIFIED))
        : codec_wrapper_(le_audio::broadcaster::getStreamConfigForContext(
                             AudioContexts(LeAudioContextType::UNSPECIFIED))
                             .first) {}

    void CheckAndReconfigureEncoders() {
@@ -880,9 +869,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      /* TODO: Should we take supported contexts from ASCS? */
      auto supported_context_types = le_audio::types::kLeAudioContextAllTypes;
      auto contexts = GetAllowedAudioContextsFromSourceMetadata(
          source_metadata,
          static_cast<std::underlying_type<LeAudioContextType>::type>(
              supported_context_types));
          source_metadata, supported_context_types);
      if (contexts.any()) {
        /* NOTICE: We probably don't want to change the stream configuration
         * on each metadata change, so just update the context type metadata.
@@ -890,7 +877,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
         * they are all mixed inside a single data stream, we will update
         * the metadata of all BIS subgroups with the same combined context.
         */
        instance->UpdateStreamingContextTypeOnAllSubgroups(contexts.to_ulong());
        instance->UpdateStreamingContextTypeOnAllSubgroups(contexts);
      }
    }

+5 −6
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@

using namespace std::chrono_literals;

using le_audio::types::AudioContexts;
using le_audio::types::LeAudioContextType;

using testing::_;
@@ -536,13 +537,11 @@ TEST_F(BroadcasterTest, UpdateMetadataFromAudioTrackMetadata) {

  // Verify context type
  ASSERT_NE(context_types_map.size(), 0u);
  uint16_t context_type;
  AudioContexts context_type;
  auto pp = context_types_map.data();
  STREAM_TO_UINT16(context_type, pp);
  ASSERT_NE(context_type &
                static_cast<std::underlying_type<LeAudioContextType>::type>(
                    LeAudioContextType::MEDIA | LeAudioContextType::GAME),
            0);
  STREAM_TO_UINT16(context_type.value_ref(), pp);
  ASSERT_TRUE(context_type.test_all(LeAudioContextType::MEDIA |
                                    LeAudioContextType::GAME));
}

TEST_F(BroadcasterTest, GetMetadata) {
+13 −30
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ static const std::pair<const BroadcastCodecWrapper&, const BroadcastQosConfig&>
    lc3_stereo_48_4_2 = {lc3_stereo_48_4, qos_config_4_65};

std::pair<const BroadcastCodecWrapper&, const BroadcastQosConfig&>
getStreamConfigForContext(uint16_t context) {
getStreamConfigForContext(types::AudioContexts context) {
  const std::string* options =
      stack_config_get_interface()->get_pts_broadcast_audio_config_options();
  if (options) {
@@ -420,41 +420,24 @@ getStreamConfigForContext(uint16_t context) {
    if (!options->compare("lc3_stereo_48_4_2")) return lc3_stereo_48_4_2;
  }
  // High quality, Low Latency
  auto contexts_stereo_24_2_1 =
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::GAME) |
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::LIVE);
  if (context & contexts_stereo_24_2_1) return lc3_stereo_24_2_1;
  if (context.test_any(LeAudioContextType::GAME | LeAudioContextType::LIVE))
    return lc3_stereo_24_2_1;

  // Low quality, Low Latency
  auto contexts_mono_16_2_1 =
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::INSTRUCTIONAL);
  if (context & contexts_mono_16_2_1) return lc3_mono_16_2_1;
  if (context.test(LeAudioContextType::INSTRUCTIONAL)) return lc3_mono_16_2_1;

  // Low quality, High Reliability
  auto contexts_stereo_16_2_2 =
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::SOUNDEFFECTS) |
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::UNSPECIFIED);
  if (context & contexts_stereo_16_2_2) return lc3_stereo_16_2_2;

  auto contexts_mono_16_2_2 =
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::ALERTS) |
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::NOTIFICATIONS) |
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::EMERGENCYALARM);
  if (context & contexts_mono_16_2_2) return lc3_mono_16_2_2;
  if (context.test_any(LeAudioContextType::SOUNDEFFECTS |
                       LeAudioContextType::UNSPECIFIED))
    return lc3_stereo_16_2_2;

  if (context.test_any(LeAudioContextType::ALERTS |
                       LeAudioContextType::NOTIFICATIONS |
                       LeAudioContextType::EMERGENCYALARM))
    return lc3_mono_16_2_2;

  // High quality, High Reliability
  auto contexts_stereo_24_2_2 =
      static_cast<std::underlying_type<LeAudioContextType>::type>(
          LeAudioContextType::MEDIA);
  if (context & contexts_stereo_24_2_2) return lc3_stereo_24_2_2;
  if (context.test(LeAudioContextType::MEDIA)) return lc3_stereo_24_2_2;

  // Defaults: Low quality, High Reliability
  return lc3_mono_16_2_2;
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ std::ostream& operator<<(
    std::ostream& os, const le_audio::broadcaster::BroadcastQosConfig& config);

std::pair<const BroadcastCodecWrapper&, const BroadcastQosConfig&>
getStreamConfigForContext(uint16_t context);
getStreamConfigForContext(types::AudioContexts context);

}  // namespace broadcaster
}  // namespace le_audio
+2 −4
Original line number Diff line number Diff line
@@ -244,10 +244,8 @@ class StateMachineTest : public Test {

    static uint8_t broadcast_id_lsb = 1;

    auto context_int = static_cast<
        std::underlying_type<le_audio::types::LeAudioContextType>::type>(
        context);
    auto codec_qos_pair = getStreamConfigForContext(context_int);
    auto codec_qos_pair =
        getStreamConfigForContext(types::AudioContexts(context));
    auto broadcast_id = broadcast_id_lsb++;
    pending_broadcasts_.push_back(BroadcastStateMachine::CreateInstance({
        .broadcast_id = broadcast_id,
Loading