Loading system/bta/include/bta_le_audio_api.h +3 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,9 @@ class LeAudioClient { bluetooth::le_audio::btle_audio_codec_config_t output_codec_config) = 0; virtual void SetCcidInformation(int ccid, int context_type) = 0; virtual void SetInCall(bool in_call) = 0; virtual bool IsInCall() = 0; virtual void SetInVoipCall(bool in_call) = 0; virtual bool IsInVoipCall() = 0; virtual void SendAudioProfilePreferences( const int group_id, bool is_output_preference_le_audio, bool is_duplex_preference_le_audio) = 0; Loading system/bta/le_audio/client.cc +72 −11 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ class LeAudioClientImpl : public LeAudioClient { audio_receiver_state_(AudioState::IDLE), audio_sender_state_(AudioState::IDLE), in_call_(false), in_voip_call_(false), current_source_codec_config({0, 0, 0, 0}), current_sink_codec_config({0, 0, 0, 0}), lc3_encoder_left_mem(nullptr), Loading Loading @@ -304,6 +305,10 @@ class LeAudioClientImpl : public LeAudioClient { void ReconfigureAfterVbcClose() { LOG_DEBUG("VBC close timeout"); if (IsInVoipCall()) { SetInVoipCall(false); } auto group = aseGroups_.FindById(active_group_id_); if (!group) { LOG_ERROR("Invalid group: %d", active_group_id_); Loading Loading @@ -917,11 +922,18 @@ class LeAudioClientImpl : public LeAudioClient { remote_contexts.source.clear(); } /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */ auto ccid_contexts = remote_contexts; if (IsInVoipCall() && !IsInCall()) { ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL); ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL); } BidirectionalPair<std::vector<uint8_t>> ccids = { .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids( remote_contexts.sink), ccid_contexts.sink), .source = ContentControlIdKeeper::GetInstance()->GetAllCcids( remote_contexts.source)}; ccid_contexts.source)}; if (group->IsPendingConfiguration()) { return groupStateMachine_->ConfigureStream( group, configuration_context_type_, remote_contexts, ccids); Loading Loading @@ -1037,6 +1049,15 @@ class LeAudioClientImpl : public LeAudioClient { in_call_ = in_call; } bool IsInCall() override { return in_call_; } void SetInVoipCall(bool in_call) override { LOG_DEBUG("in_voip_call: %d", in_call); in_voip_call_ = in_call; } bool IsInVoipCall() override { return in_voip_call_; } void SendAudioProfilePreferences( const int group_id, bool is_output_preference_le_audio, bool is_duplex_preference_le_audio) override { Loading Loading @@ -2943,7 +2964,20 @@ class LeAudioClientImpl : public LeAudioClient { return; } if (!groupStateMachine_->AttachToStream(group, leAudioDevice)) { /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */ auto ccid_contexts = group->GetMetadataContexts(); if (IsInVoipCall() && !IsInCall()) { ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL); ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL); } BidirectionalPair<std::vector<uint8_t>> ccids = { .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids( ccid_contexts.sink), .source = ContentControlIdKeeper::GetInstance()->GetAllCcids( ccid_contexts.source)}; if (!groupStateMachine_->AttachToStream(group, leAudioDevice, std::move(ccids))) { LOG_WARN("Could not add device %s to the group %d streaming. ", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), group->group_id_); Loading Loading @@ -3898,7 +3932,7 @@ class LeAudioClientImpl : public LeAudioClient { } /* Check if the device resume is expected */ if (!group->GetCachedCodecConfigurationByDirection( if (!group->GetCodecConfigurationByDirection( configuration_context_type_, le_audio::types::kLeAudioDirectionSink)) { LOG(ERROR) << __func__ << ", invalid resume request for context type: " Loading Loading @@ -4324,7 +4358,7 @@ class LeAudioClientImpl : public LeAudioClient { bluetooth::common::ToString(available_remote_contexts).c_str(), bluetooth::common::ToString(configuration_context_type_).c_str()); if (in_call_) { if (IsInCall()) { LOG_DEBUG(" In Call preference used."); return LeAudioContextType::CONVERSATIONAL; } Loading @@ -4336,10 +4370,10 @@ class LeAudioClientImpl : public LeAudioClient { LeAudioContextType context_priority_list[] = { /* Highest priority first */ LeAudioContextType::CONVERSATIONAL, /* Skip the RINGTONE to avoid reconfigurations when adjusting * call volume slider while not in a call. * LeAudioContextType::RINGTONE, /* Handling RINGTONE will cause the ringtone volume slider to trigger * reconfiguration. This will be fixed in b/283349711. */ LeAudioContextType::RINGTONE, LeAudioContextType::LIVE, LeAudioContextType::VOICEASSISTANTS, LeAudioContextType::GAME, Loading Loading @@ -4600,11 +4634,29 @@ class LeAudioClientImpl : public LeAudioClient { BidirectionalPair<AudioContexts> DirectionalRealignMetadataAudioContexts( LeAudioDeviceGroup* group, int remote_direction) { // Inject conversational when ringtone is played - this is required for all // the VoIP applications which are not using the telecom API. if ((remote_direction == le_audio::types::kLeAudioDirectionSink) && local_metadata_context_types_.source.test( LeAudioContextType::RINGTONE)) { /* Simulate, we are already in the call. Sending RINGTONE when there is * no incoming call to accept or reject on TBS could confuse the remote * device and interrupt the stream establish procedure. */ if (!IsInCall()) { SetInVoipCall(true); } } else if (IsInVoipCall()) { SetInVoipCall(false); } /* Make sure we have CONVERSATIONAL when in a call and it is not mixed * with any other bidirectional context */ if (in_call_) { LOG_DEBUG(" In Call preference used."); if (IsInCall() || IsInVoipCall()) { LOG_DEBUG(" In Call preference used: %s, voip call: %s", (IsInCall() ? "true" : "false"), (IsInVoipCall() ? "true" : "false")); local_metadata_context_types_.sink.unset_all(kLeAudioContextAllBidir); local_metadata_context_types_.source.unset_all(kLeAudioContextAllBidir); local_metadata_context_types_.sink.set( Loading Loading @@ -4634,6 +4686,12 @@ class LeAudioClientImpl : public LeAudioClient { BidirectionalPair<AudioContexts> remote_metadata = { .sink = local_metadata_context_types_.source, .source = local_metadata_context_types_.sink}; if (IsInVoipCall()) { LOG_DEBUG("Unsetting RINGTONE from remote sink "); remote_metadata.sink.unset(LeAudioContextType::RINGTONE); } LOG_DEBUG("local_metadata_context_types_.source= %s", ToString(local_metadata_context_types_.source).c_str()); LOG_DEBUG("local_metadata_context_types_.sink= %s", Loading Loading @@ -5135,11 +5193,13 @@ class LeAudioClientImpl : public LeAudioClient { false)) { return; } /* If group is inactive, phone is in call and Group is not having CIS * connected, notify upper layer about it, so it can decide to create SCO if * it is in the handover case */ if (in_call_ && active_group_id_ == bluetooth::groups::kGroupUnknown) { if ((IsInCall() || IsInVoipCall()) && active_group_id_ == bluetooth::groups::kGroupUnknown) { callbacks_->OnGroupStatus(group_id, GroupStatus::TURNED_IDLE_DURING_CALL); } } Loading Loading @@ -5313,6 +5373,7 @@ class LeAudioClientImpl : public LeAudioClient { AudioState audio_sender_state_; /* Keep in call state. */ bool in_call_; bool in_voip_call_; /* Reconnection mode */ tBTM_BLE_CONN_TYPE reconnection_mode_; Loading system/bta/le_audio/le_audio_client_test.cc +5 −3 Original line number Diff line number Diff line Loading @@ -739,16 +739,18 @@ class UnicastTestNoInit : public Test { return true; }); ON_CALL(mock_state_machine_, AttachToStream(_, _)) ON_CALL(mock_state_machine_, AttachToStream(_, _, _)) .WillByDefault([](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) { LeAudioDevice* leAudioDevice, types::BidirectionalPair<std::vector<uint8_t>> ccids) { if (group->GetState() != types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) { return false; } group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts()); group->GetMetadataContexts(), ccids); if (!group->CigAssignCisIds(leAudioDevice)) return false; group->CigAssignCisConnHandlesToAses(leAudioDevice); Loading system/bta/le_audio/mock_state_machine.h +2 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,8 @@ class MockLeAudioGroupStateMachine : public le_audio::LeAudioGroupStateMachine { (override)); MOCK_METHOD((bool), AttachToStream, (le_audio::LeAudioDeviceGroup * group, le_audio::LeAudioDevice* leAudioDevice), le_audio::LeAudioDevice* leAudioDevice, le_audio::types::BidirectionalPair<std::vector<uint8_t>> ccids), (override)); MOCK_METHOD((void), SuspendStream, (le_audio::LeAudioDeviceGroup * group), (override)); Loading system/bta/le_audio/state_machine.cc +2 −7 Original line number Diff line number Diff line Loading @@ -137,8 +137,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { log_history_ = nullptr; } bool AttachToStream(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) override { bool AttachToStream(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice, BidirectionalPair<std::vector<uint8_t>> ccids) override { LOG(INFO) << __func__ << " group id: " << group->group_id_ << " device: " << ADDRESS_TO_LOGGABLE_STR(leAudioDevice->address_); Loading @@ -155,11 +155,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return false; } BidirectionalPair<std::vector<uint8_t>> ccids = { .sink = le_audio::ContentControlIdKeeper::GetInstance()->GetAllCcids( group->GetMetadataContexts().sink), .source = le_audio::ContentControlIdKeeper::GetInstance()->GetAllCcids( group->GetMetadataContexts().source)}; if (!group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts(), ccids)) { LOG_ERROR(" failed to set ASE configuration"); Loading Loading
system/bta/include/bta_le_audio_api.h +3 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,9 @@ class LeAudioClient { bluetooth::le_audio::btle_audio_codec_config_t output_codec_config) = 0; virtual void SetCcidInformation(int ccid, int context_type) = 0; virtual void SetInCall(bool in_call) = 0; virtual bool IsInCall() = 0; virtual void SetInVoipCall(bool in_call) = 0; virtual bool IsInVoipCall() = 0; virtual void SendAudioProfilePreferences( const int group_id, bool is_output_preference_le_audio, bool is_duplex_preference_le_audio) = 0; Loading
system/bta/le_audio/client.cc +72 −11 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ class LeAudioClientImpl : public LeAudioClient { audio_receiver_state_(AudioState::IDLE), audio_sender_state_(AudioState::IDLE), in_call_(false), in_voip_call_(false), current_source_codec_config({0, 0, 0, 0}), current_sink_codec_config({0, 0, 0, 0}), lc3_encoder_left_mem(nullptr), Loading Loading @@ -304,6 +305,10 @@ class LeAudioClientImpl : public LeAudioClient { void ReconfigureAfterVbcClose() { LOG_DEBUG("VBC close timeout"); if (IsInVoipCall()) { SetInVoipCall(false); } auto group = aseGroups_.FindById(active_group_id_); if (!group) { LOG_ERROR("Invalid group: %d", active_group_id_); Loading Loading @@ -917,11 +922,18 @@ class LeAudioClientImpl : public LeAudioClient { remote_contexts.source.clear(); } /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */ auto ccid_contexts = remote_contexts; if (IsInVoipCall() && !IsInCall()) { ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL); ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL); } BidirectionalPair<std::vector<uint8_t>> ccids = { .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids( remote_contexts.sink), ccid_contexts.sink), .source = ContentControlIdKeeper::GetInstance()->GetAllCcids( remote_contexts.source)}; ccid_contexts.source)}; if (group->IsPendingConfiguration()) { return groupStateMachine_->ConfigureStream( group, configuration_context_type_, remote_contexts, ccids); Loading Loading @@ -1037,6 +1049,15 @@ class LeAudioClientImpl : public LeAudioClient { in_call_ = in_call; } bool IsInCall() override { return in_call_; } void SetInVoipCall(bool in_call) override { LOG_DEBUG("in_voip_call: %d", in_call); in_voip_call_ = in_call; } bool IsInVoipCall() override { return in_voip_call_; } void SendAudioProfilePreferences( const int group_id, bool is_output_preference_le_audio, bool is_duplex_preference_le_audio) override { Loading Loading @@ -2943,7 +2964,20 @@ class LeAudioClientImpl : public LeAudioClient { return; } if (!groupStateMachine_->AttachToStream(group, leAudioDevice)) { /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */ auto ccid_contexts = group->GetMetadataContexts(); if (IsInVoipCall() && !IsInCall()) { ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL); ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL); } BidirectionalPair<std::vector<uint8_t>> ccids = { .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids( ccid_contexts.sink), .source = ContentControlIdKeeper::GetInstance()->GetAllCcids( ccid_contexts.source)}; if (!groupStateMachine_->AttachToStream(group, leAudioDevice, std::move(ccids))) { LOG_WARN("Could not add device %s to the group %d streaming. ", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), group->group_id_); Loading Loading @@ -3898,7 +3932,7 @@ class LeAudioClientImpl : public LeAudioClient { } /* Check if the device resume is expected */ if (!group->GetCachedCodecConfigurationByDirection( if (!group->GetCodecConfigurationByDirection( configuration_context_type_, le_audio::types::kLeAudioDirectionSink)) { LOG(ERROR) << __func__ << ", invalid resume request for context type: " Loading Loading @@ -4324,7 +4358,7 @@ class LeAudioClientImpl : public LeAudioClient { bluetooth::common::ToString(available_remote_contexts).c_str(), bluetooth::common::ToString(configuration_context_type_).c_str()); if (in_call_) { if (IsInCall()) { LOG_DEBUG(" In Call preference used."); return LeAudioContextType::CONVERSATIONAL; } Loading @@ -4336,10 +4370,10 @@ class LeAudioClientImpl : public LeAudioClient { LeAudioContextType context_priority_list[] = { /* Highest priority first */ LeAudioContextType::CONVERSATIONAL, /* Skip the RINGTONE to avoid reconfigurations when adjusting * call volume slider while not in a call. * LeAudioContextType::RINGTONE, /* Handling RINGTONE will cause the ringtone volume slider to trigger * reconfiguration. This will be fixed in b/283349711. */ LeAudioContextType::RINGTONE, LeAudioContextType::LIVE, LeAudioContextType::VOICEASSISTANTS, LeAudioContextType::GAME, Loading Loading @@ -4600,11 +4634,29 @@ class LeAudioClientImpl : public LeAudioClient { BidirectionalPair<AudioContexts> DirectionalRealignMetadataAudioContexts( LeAudioDeviceGroup* group, int remote_direction) { // Inject conversational when ringtone is played - this is required for all // the VoIP applications which are not using the telecom API. if ((remote_direction == le_audio::types::kLeAudioDirectionSink) && local_metadata_context_types_.source.test( LeAudioContextType::RINGTONE)) { /* Simulate, we are already in the call. Sending RINGTONE when there is * no incoming call to accept or reject on TBS could confuse the remote * device and interrupt the stream establish procedure. */ if (!IsInCall()) { SetInVoipCall(true); } } else if (IsInVoipCall()) { SetInVoipCall(false); } /* Make sure we have CONVERSATIONAL when in a call and it is not mixed * with any other bidirectional context */ if (in_call_) { LOG_DEBUG(" In Call preference used."); if (IsInCall() || IsInVoipCall()) { LOG_DEBUG(" In Call preference used: %s, voip call: %s", (IsInCall() ? "true" : "false"), (IsInVoipCall() ? "true" : "false")); local_metadata_context_types_.sink.unset_all(kLeAudioContextAllBidir); local_metadata_context_types_.source.unset_all(kLeAudioContextAllBidir); local_metadata_context_types_.sink.set( Loading Loading @@ -4634,6 +4686,12 @@ class LeAudioClientImpl : public LeAudioClient { BidirectionalPair<AudioContexts> remote_metadata = { .sink = local_metadata_context_types_.source, .source = local_metadata_context_types_.sink}; if (IsInVoipCall()) { LOG_DEBUG("Unsetting RINGTONE from remote sink "); remote_metadata.sink.unset(LeAudioContextType::RINGTONE); } LOG_DEBUG("local_metadata_context_types_.source= %s", ToString(local_metadata_context_types_.source).c_str()); LOG_DEBUG("local_metadata_context_types_.sink= %s", Loading Loading @@ -5135,11 +5193,13 @@ class LeAudioClientImpl : public LeAudioClient { false)) { return; } /* If group is inactive, phone is in call and Group is not having CIS * connected, notify upper layer about it, so it can decide to create SCO if * it is in the handover case */ if (in_call_ && active_group_id_ == bluetooth::groups::kGroupUnknown) { if ((IsInCall() || IsInVoipCall()) && active_group_id_ == bluetooth::groups::kGroupUnknown) { callbacks_->OnGroupStatus(group_id, GroupStatus::TURNED_IDLE_DURING_CALL); } } Loading Loading @@ -5313,6 +5373,7 @@ class LeAudioClientImpl : public LeAudioClient { AudioState audio_sender_state_; /* Keep in call state. */ bool in_call_; bool in_voip_call_; /* Reconnection mode */ tBTM_BLE_CONN_TYPE reconnection_mode_; Loading
system/bta/le_audio/le_audio_client_test.cc +5 −3 Original line number Diff line number Diff line Loading @@ -739,16 +739,18 @@ class UnicastTestNoInit : public Test { return true; }); ON_CALL(mock_state_machine_, AttachToStream(_, _)) ON_CALL(mock_state_machine_, AttachToStream(_, _, _)) .WillByDefault([](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) { LeAudioDevice* leAudioDevice, types::BidirectionalPair<std::vector<uint8_t>> ccids) { if (group->GetState() != types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) { return false; } group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts()); group->GetMetadataContexts(), ccids); if (!group->CigAssignCisIds(leAudioDevice)) return false; group->CigAssignCisConnHandlesToAses(leAudioDevice); Loading
system/bta/le_audio/mock_state_machine.h +2 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,8 @@ class MockLeAudioGroupStateMachine : public le_audio::LeAudioGroupStateMachine { (override)); MOCK_METHOD((bool), AttachToStream, (le_audio::LeAudioDeviceGroup * group, le_audio::LeAudioDevice* leAudioDevice), le_audio::LeAudioDevice* leAudioDevice, le_audio::types::BidirectionalPair<std::vector<uint8_t>> ccids), (override)); MOCK_METHOD((void), SuspendStream, (le_audio::LeAudioDeviceGroup * group), (override)); Loading
system/bta/le_audio/state_machine.cc +2 −7 Original line number Diff line number Diff line Loading @@ -137,8 +137,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { log_history_ = nullptr; } bool AttachToStream(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) override { bool AttachToStream(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice, BidirectionalPair<std::vector<uint8_t>> ccids) override { LOG(INFO) << __func__ << " group id: " << group->group_id_ << " device: " << ADDRESS_TO_LOGGABLE_STR(leAudioDevice->address_); Loading @@ -155,11 +155,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return false; } BidirectionalPair<std::vector<uint8_t>> ccids = { .sink = le_audio::ContentControlIdKeeper::GetInstance()->GetAllCcids( group->GetMetadataContexts().sink), .source = le_audio::ContentControlIdKeeper::GetInstance()->GetAllCcids( group->GetMetadataContexts().source)}; if (!group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts(), ccids)) { LOG_ERROR(" failed to set ASE configuration"); Loading