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

Commit 97f2d3a8 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
parent d3b8e9f2
Loading
Loading
Loading
Loading
+20 −33
Original line number Original line Diff line number Diff line
@@ -48,6 +48,7 @@ using le_audio::broadcaster::BroadcastQosConfig;
using le_audio::broadcaster::BroadcastStateMachine;
using le_audio::broadcaster::BroadcastStateMachine;
using le_audio::broadcaster::BroadcastStateMachineConfig;
using le_audio::broadcaster::BroadcastStateMachineConfig;
using le_audio::broadcaster::IBroadcastStateMachineCallbacks;
using le_audio::broadcaster::IBroadcastStateMachineCallbacks;
using le_audio::types::AudioContexts;
using le_audio::types::CodecLocation;
using le_audio::types::CodecLocation;
using le_audio::types::kLeAudioCodingFormatLC3;
using le_audio::types::kLeAudioCodingFormatLC3;
using le_audio::types::LeAudioContextType;
using le_audio::types::LeAudioContextType;
@@ -168,18 +169,18 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    return announcement;
    return announcement;
  }
  }


  void UpdateStreamingContextTypeOnAllSubgroups(uint16_t context_type_map) {
  void UpdateStreamingContextTypeOnAllSubgroups(const AudioContexts& contexts) {
    LOG_DEBUG("%s context_type_map=%d", __func__, context_type_map);
    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()) {
    if (ccids.empty()) {
      LOG_WARN("%s No content providers available for context_type_map=%d.",
      LOG_WARN("%s No content providers available for context_type_map=%s.",
               __func__, context_type_map);
               __func__, contexts.to_string().c_str());
    }
    }


    std::vector<uint8_t> stream_context_vec(2);
    std::vector<uint8_t> stream_context_vec(2);
    auto pp = stream_context_vec.data();
    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_) {
    for (auto const& kv_it : broadcasts_) {
      auto& broadcast = kv_it.second;
      auto& broadcast = kv_it.second;
@@ -262,9 +263,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      return;
      return;
    }
    }


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


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


@@ -290,7 +286,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
        ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
        ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
    if (stream_context_vec) {
    if (stream_context_vec) {
      auto pp = stream_context_vec.value().data();
      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
    // Append the CCID list
@@ -322,9 +318,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      return;
      return;
    }
    }


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


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


@@ -350,7 +341,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
        ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
        ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
    if (stream_context_vec) {
    if (stream_context_vec) {
      auto pp = stream_context_vec.value().data();
      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
    // Append the CCID list
@@ -738,10 +729,8 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      : public LeAudioSourceAudioHalClient::Callbacks {
      : public LeAudioSourceAudioHalClient::Callbacks {
   public:
   public:
    LeAudioSourceCallbacksImpl()
    LeAudioSourceCallbacksImpl()
        : codec_wrapper_(
        : codec_wrapper_(le_audio::broadcaster::getStreamConfigForContext(
              le_audio::broadcaster::getStreamConfigForContext(
                             AudioContexts(LeAudioContextType::UNSPECIFIED))
                  static_cast<std::underlying_type<LeAudioContextType>::type>(
                      le_audio::types::LeAudioContextType::UNSPECIFIED))
                             .first) {}
                             .first) {}


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


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


using namespace std::chrono_literals;
using namespace std::chrono_literals;


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


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


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


TEST_F(BroadcasterTest, GetMetadata) {
TEST_F(BroadcasterTest, GetMetadata) {
+13 −30
Original line number Original line 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};
    lc3_stereo_48_4_2 = {lc3_stereo_48_4, qos_config_4_65};


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


  // Low quality, Low Latency
  // Low quality, Low Latency
  auto contexts_mono_16_2_1 =
  if (context.test(LeAudioContextType::INSTRUCTIONAL)) return lc3_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;


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

          LeAudioContextType::UNSPECIFIED);
  if (context.test_any(LeAudioContextType::ALERTS |
  if (context & contexts_stereo_16_2_2) return lc3_stereo_16_2_2;
                       LeAudioContextType::NOTIFICATIONS |

                       LeAudioContextType::EMERGENCYALARM))
  auto contexts_mono_16_2_2 =
    return lc3_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;


  // High quality, High Reliability
  // High quality, High Reliability
  auto contexts_stereo_24_2_2 =
  if (context.test(LeAudioContextType::MEDIA)) return lc3_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;


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


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


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


    static uint8_t broadcast_id_lsb = 1;
    static uint8_t broadcast_id_lsb = 1;


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