Loading system/btif/co/bta_av_co.cc +150 −25 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "btif/include/bta_av_co.h" #include <android_bluetooth_flags.h> #include <bluetooth/log.h> #include <mutex> Loading Loading @@ -105,6 +106,8 @@ void BtaAvCo::Init( void BtaAvCo::Reset() { bta_av_legacy_state_.Reset(); bta_av_source_state_.Reset(); bta_av_sink_state_.Reset(); content_protect_flag_ = 0; if (ContentProtectEnabled()) { Loading @@ -130,7 +133,13 @@ bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) { A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() { std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = nullptr; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { reference_state = &bta_av_source_state_; } else { reference_state = &bta_av_legacy_state_; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); if (active_peer == nullptr || active_peer->GetCodecs() == nullptr) { return nullptr; } Loading Loading @@ -530,7 +539,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, if (codec_config_supported) { // If Peer is Source, and our config subset matches with what is // requested by peer, then just accept what peer wants. SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info); SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info, t_local_sep); } } if (t_local_sep == AVDT_TSEP_SRC) { Loading @@ -541,7 +551,7 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, bool dummy_restart_output = false; if ((p_peer->GetCodecs() == nullptr) || !SetCodecOtaConfig(p_peer, p_codec_info, num_protect, p_protect_info, &dummy_restart_output)) { &dummy_restart_output, t_local_sep)) { log::error("cannot set source codec {} for peer {}", A2DP_CodecName(p_codec_info), ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); Loading Loading @@ -596,10 +606,14 @@ void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle, p_peer->opened = true; p_peer->mtu = mtu; // The first connected peer becomes the active peer BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = getStateFromPeer(p_peer); if (reference_state == nullptr) { log::warn("Invalid bta av state"); return; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); if (active_peer == nullptr) { bta_av_legacy_state_.setActivePeer(p_peer); reference_state->setActivePeer(p_peer); } } Loading @@ -618,10 +632,17 @@ void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle, return; } // Reset the active peer BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = getStateFromPeer(p_peer); if (reference_state == nullptr) { log::warn("Invalid bta av state"); return; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); if (active_peer == p_peer) { bta_av_legacy_state_.setActivePeer(nullptr); reference_state->setActivePeer(nullptr); } // Mark the peer closed and clean the peer info p_peer->Init(peer_cache_->codec_priorities_); } Loading Loading @@ -686,7 +707,13 @@ BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info, return nullptr; } BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = nullptr; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { reference_state = &bta_av_source_state_; } else { reference_state = &bta_av_legacy_state_; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); // if offset is 0, the decremental operation may result in // underflow and OOB access if (ContentProtectEnabled() && (active_peer != nullptr) && Loading Loading @@ -731,12 +758,19 @@ void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle, p_peer->mtu = mtu; } bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) { bool BtaAvCo::SetActivePeer(const RawAddress& peer_address, const uint8_t t_local_sep) { log::info("peer_address={}", ADDRESS_TO_LOGGABLE_STR(peer_address)); std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); BtaAvCoState* reference_state = &bta_av_legacy_state_; BtaAvCoState* reference_state = getStateFromLocalProfile(t_local_sep); if (reference_state == nullptr) { log::warn( "Invalid bta av state for peer_address : {} with local sep as :{}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), t_local_sep); return false; } if (peer_address.IsEmpty()) { // Reset the active peer; reference_state->setActivePeer(nullptr); Loading @@ -759,9 +793,28 @@ bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) { return true; } BtaAvCoState* BtaAvCo::getStateFromLocalProfile(const uint8_t t_local_sep) { if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (t_local_sep == AVDT_TSEP_SRC) { return &bta_av_source_state_; } else if (t_local_sep == AVDT_TSEP_SNK) { return &bta_av_sink_state_; } else { log::warn("Invalid bta av state for local sep type {}", t_local_sep); return nullptr; } } else { return &bta_av_legacy_state_; } } void BtaAvCo::SaveCodec(const uint8_t* new_codec_config) { if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { bta_av_sink_state_.setCodecConfig(new_codec_config); } else { bta_av_legacy_state_.setCodecConfig(new_codec_config); } } void BtaAvCo::GetPeerEncoderParameters( const RawAddress& peer_address, Loading Loading @@ -792,7 +845,9 @@ void BtaAvCo::GetPeerEncoderParameters( const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() { std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { return A2DP_GetEncoderInterface(bta_av_source_state_.getCodecConfig()); } return A2DP_GetEncoderInterface(bta_av_legacy_state_.getCodecConfig()); } Loading Loading @@ -887,7 +942,12 @@ done: // and informing the Media Framework about the change. // Find the peer that is currently open BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoPeer* active_peer; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { active_peer = bta_av_source_state_.getActivePeer(); } else { active_peer = bta_av_legacy_state_.getActivePeer(); } if (p_peer != nullptr && (!restart_output || !success || p_peer != active_peer)) { return ReportSourceCodecState(p_peer); Loading @@ -905,7 +965,12 @@ bool BtaAvCo::SetCodecAudioConfig( log::verbose("codec_audio_config: {}", codec_audio_config.ToString()); // Find the peer that is currently open BtaAvCoPeer* p_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoPeer* p_peer; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { p_peer = bta_av_source_state_.getActivePeer(); } else { p_peer = bta_av_legacy_state_.getActivePeer(); } if (p_peer == nullptr) { log::error("no active peer to configure"); return false; Loading Loading @@ -942,7 +1007,7 @@ bool BtaAvCo::SetCodecAudioConfig( } SaveNewCodecConfig(p_peer, result_codec_config, p_sink->num_protect, p_sink->protect_info); p_sink->protect_info, AVDT_TSEP_SRC); p_peer->acceptor = false; log::verbose("call BTA_AvReconfig({})", loghex(p_peer->BtaAvHandle())); Loading @@ -962,6 +1027,10 @@ bool BtaAvCo::SetCodecAudioConfig( int BtaAvCo::GetSourceEncoderEffectiveFrameSize() { std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { return A2DP_GetEecoderEffectiveFrameSize( bta_av_source_state_.getCodecConfig()); } return A2DP_GetEecoderEffectiveFrameSize( bta_av_legacy_state_.getCodecConfig()); } Loading Loading @@ -1022,6 +1091,18 @@ void BtaAvCo::DebugDump(int fd) { a2dp_codecs->debug_codec_dump(fd); } } if (bta_av_source_state_.getActivePeer() != nullptr) { A2dpCodecs* a2dp_codecs = bta_av_source_state_.getActivePeer()->GetCodecs(); if (a2dp_codecs != nullptr) { a2dp_codecs->debug_codec_dump(fd); } } if (bta_av_sink_state_.getActivePeer() != nullptr) { A2dpCodecs* a2dp_codecs = bta_av_sink_state_.getActivePeer()->GetCodecs(); if (a2dp_codecs != nullptr) { a2dp_codecs->debug_codec_dump(fd); } } dprintf(fd, "\nA2DP Peers State:\n"); dprintf( Loading @@ -1029,6 +1110,16 @@ void BtaAvCo::DebugDump(int fd) { (bta_av_legacy_state_.getActivePeer() != nullptr) ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_legacy_state_.getActivePeer()->addr) : "null"); dprintf( fd, " Source: active peer: %s\n", (bta_av_source_state_.getActivePeer() != nullptr) ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_source_state_.getActivePeer()->addr) : "null"); dprintf( fd, " Sink: active peer: %s\n", (bta_av_sink_state_.getActivePeer() != nullptr) ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_sink_state_.getActivePeer()->addr) : "null"); for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) { const BtaAvCoPeer& peer = peer_cache_->peers_[i]; Loading Loading @@ -1108,7 +1199,7 @@ BtaAvCoSep* BtaAvCo::SelectProviderCodecConfiguration( p_peer->GetCodecs()->setCurrentCodecConfig(codec_config); p_peer->p_sink = p_sink; SaveNewCodecConfig(p_peer, provider_codec_config.codec_config, p_sink->num_protect, p_sink->protect_info); p_sink->num_protect, p_sink->protect_info, AVDT_TSEP_SRC); return p_sink; } Loading Loading @@ -1216,7 +1307,7 @@ const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection( p_peer->p_sink = p_sink; SaveNewCodecConfig(p_peer, new_codec_config, p_sink->num_protect, p_sink->protect_info); p_sink->protect_info, AVDT_TSEP_SRC); return p_sink; } Loading @@ -1243,7 +1334,7 @@ const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection( p_peer->p_source = p_source; SaveNewCodecConfig(p_peer, new_codec_config, p_source->num_protect, p_source->protect_info); p_source->protect_info, AVDT_TSEP_SNK); return p_source; } Loading Loading @@ -1318,12 +1409,20 @@ bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config, void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, uint8_t num_protect, const uint8_t* p_protect_info) { const uint8_t* p_protect_info, const uint8_t t_local_sep) { log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); log::verbose("codec: {}", A2DP_CodecInfoString(new_codec_config)); std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); bta_av_legacy_state_.setCodecConfig(new_codec_config); BtaAvCoState* reference_state = getStateFromLocalProfile(t_local_sep); if (reference_state == nullptr) { log::warn( "Invalid bta av state for peer_address : {} with local sep as :{}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), t_local_sep); return; } reference_state->setCodecConfig(new_codec_config); memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE); if (ContentProtectEnabled()) { Loading @@ -1333,11 +1432,29 @@ void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer, } } BtaAvCoState* BtaAvCo::getStateFromPeer(const BtaAvCoPeer* p_peer) { if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SINK) { return &bta_av_source_state_; } else if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) { return &bta_av_sink_state_; } else { log::warn("Invalid bta av state for peer_address : {} with uuid as :{}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), p_peer->uuid_to_connect); return nullptr; } } else { return &bta_av_legacy_state_; } } bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, uint8_t num_protect, const uint8_t* p_protect_info, bool* p_restart_output) { bool* p_restart_output, const uint8_t t_local_sep) { uint8_t result_codec_config[AVDT_CODEC_SIZE]; bool restart_input = false; bool restart_output = false; Loading Loading @@ -1376,8 +1493,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, *p_restart_output = true; p_peer->p_sink = p_sink; SaveNewCodecConfig(p_peer, result_codec_config, num_protect, p_protect_info); SaveNewCodecConfig(p_peer, result_codec_config, num_protect, p_protect_info, t_local_sep); } if (restart_input || config_updated) { Loading Loading @@ -1569,7 +1686,15 @@ void bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle, } bool bta_av_co_set_active_peer(const RawAddress& peer_address) { return bta_av_co_cb.SetActivePeer(peer_address); return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_INVALID); } bool bta_av_co_set_active_sink_peer(const RawAddress& peer_address) { return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_SNK); } bool bta_av_co_set_active_source_peer(const RawAddress& peer_address) { return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_SRC); } void bta_av_co_save_codec(const uint8_t* new_codec_config) { Loading system/btif/include/bta_av_co.h +25 −4 Original line number Diff line number Diff line Loading @@ -288,9 +288,10 @@ class BtaAvCo { * Set the active peer. * * @param peer_address the peer address * @param t_local_sep update the active peer for the profile type. * @return true on success, otherwise false */ bool SetActivePeer(const RawAddress& peer_address); bool SetActivePeer(const RawAddress& peer_address, const uint8_t t_local_sep); /** * Save the reconfig codec Loading Loading @@ -434,9 +435,12 @@ class BtaAvCo { * @param new_codec_config the new codec configuration to use * @param num_protect the number of content protection elements * @param p_protect_info the content protection info to use * @param t_local_sep the profile for which the codec config needs to be * saved. */ void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, uint8_t num_protect, const uint8_t* p_protect_info); uint8_t num_protect, const uint8_t* p_protect_info, const uint8_t t_local_sep); /** * Set the Over-The-Air preferred codec configuration. Loading @@ -455,11 +459,12 @@ class BtaAvCo { * @param p_restart_output if there is a change in the encoder configuration * that requires restarting of the A2DP connection, flag |p_restart_output| * is set to true. * @param t_local_sep the profile for which ota config needs to be set. * @return true on success, otherwise false */ bool SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, uint8_t num_protect, const uint8_t* p_protect_info, bool* p_restart_output); bool* p_restart_output, const uint8_t t_local_sep); /** * Update all selectable Source codecs with the corresponding codec Loading Loading @@ -540,9 +545,25 @@ class BtaAvCo { const ::bluetooth::audio::a2dp::provider::a2dp_configuration& provider_codec_config); /** * Returns the state that needs to be accessed. * @param p_peer peer address. * @return state of the profile. */ BtaAvCoState* getStateFromPeer(const BtaAvCoPeer* p_peer); /** * Returns the state based on the local profile of the stack. * @param t_local_sep local sep type * @return state of the profile. */ BtaAvCoState* getStateFromLocalProfile(const uint8_t t_local_sep); bool ContentProtectEnabled() const { return content_protect_enabled_; } const bool content_protect_enabled_; // True if Content Protect is enabled uint8_t content_protect_flag_; // Content Protect flag BtaAvCoState bta_av_legacy_state_; BtaAvCoState bta_av_legacy_state_; // Legacy state BtaAvCoState bta_av_source_state_; // Source profile state BtaAvCoState bta_av_sink_state_; // Sink profile state }; system/btif/include/btif_av_co.h +14 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,20 @@ // Returns true on success, otherwise false. bool bta_av_co_set_active_peer(const RawAddress& peer_addr); /** * Sets the active peer within the sink profile of the bta av co instance. * @param peer_address peer address of the remote device. * @return true on success, otherwise false. */ bool bta_av_co_set_active_sink_peer(const RawAddress& peer_address); /** * Sets the active peer within the sink profile of the bta av co instance. * @param peer_address peer address of the remote device. * @return true on success, otherwise false. */ bool bta_av_co_set_active_source_peer(const RawAddress& peer_address); void bta_av_co_save_codec(const uint8_t* new_codec_config); // Gets the A2DP peer parameters that are used to initialize the encoder. Loading system/btif/src/btif_a2dp_sink.cc +15 −6 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "btif/include/btif_a2dp_sink.h" #include <android_bluetooth_flags.h> #include <base/functional/bind.h> #include <base/logging.h> #include <bluetooth/log.h> Loading Loading @@ -258,13 +259,21 @@ bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address, if (!old_peer_address.IsEmpty()) { btif_a2dp_sink_end_session(old_peer_address); } if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (!bta_av_co_set_active_sink_peer(new_peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_STR(new_peer_address)); peer_ready_promise.set_value(); return false; } } else { if (!bta_av_co_set_active_peer(new_peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_STR(new_peer_address)); peer_ready_promise.set_value(); return false; } } if (old_peer_address.IsEmpty()) { btif_a2dp_sink_startup(); Loading system/btif/src/btif_a2dp_source.cc +12 −5 Original line number Diff line number Diff line Loading @@ -578,12 +578,19 @@ static void btif_a2dp_source_setup_codec_delayed( tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; bta_av_co_get_peer_params(peer_address, &peer_params); if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (!bta_av_co_set_active_source_peer(peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } } else { if (!bta_av_co_set_active_peer(peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } } btif_a2dp_source_cb.encoder_interface = bta_av_co_get_encoder_interface(); if (btif_a2dp_source_cb.encoder_interface == nullptr) { log::error("Cannot stream audio: no source encoder interface"); Loading Loading
system/btif/co/bta_av_co.cc +150 −25 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "btif/include/bta_av_co.h" #include <android_bluetooth_flags.h> #include <bluetooth/log.h> #include <mutex> Loading Loading @@ -105,6 +106,8 @@ void BtaAvCo::Init( void BtaAvCo::Reset() { bta_av_legacy_state_.Reset(); bta_av_source_state_.Reset(); bta_av_sink_state_.Reset(); content_protect_flag_ = 0; if (ContentProtectEnabled()) { Loading @@ -130,7 +133,13 @@ bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) { A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() { std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = nullptr; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { reference_state = &bta_av_source_state_; } else { reference_state = &bta_av_legacy_state_; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); if (active_peer == nullptr || active_peer->GetCodecs() == nullptr) { return nullptr; } Loading Loading @@ -530,7 +539,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, if (codec_config_supported) { // If Peer is Source, and our config subset matches with what is // requested by peer, then just accept what peer wants. SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info); SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info, t_local_sep); } } if (t_local_sep == AVDT_TSEP_SRC) { Loading @@ -541,7 +551,7 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, bool dummy_restart_output = false; if ((p_peer->GetCodecs() == nullptr) || !SetCodecOtaConfig(p_peer, p_codec_info, num_protect, p_protect_info, &dummy_restart_output)) { &dummy_restart_output, t_local_sep)) { log::error("cannot set source codec {} for peer {}", A2DP_CodecName(p_codec_info), ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); Loading Loading @@ -596,10 +606,14 @@ void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle, p_peer->opened = true; p_peer->mtu = mtu; // The first connected peer becomes the active peer BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = getStateFromPeer(p_peer); if (reference_state == nullptr) { log::warn("Invalid bta av state"); return; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); if (active_peer == nullptr) { bta_av_legacy_state_.setActivePeer(p_peer); reference_state->setActivePeer(p_peer); } } Loading @@ -618,10 +632,17 @@ void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle, return; } // Reset the active peer BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = getStateFromPeer(p_peer); if (reference_state == nullptr) { log::warn("Invalid bta av state"); return; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); if (active_peer == p_peer) { bta_av_legacy_state_.setActivePeer(nullptr); reference_state->setActivePeer(nullptr); } // Mark the peer closed and clean the peer info p_peer->Init(peer_cache_->codec_priorities_); } Loading Loading @@ -686,7 +707,13 @@ BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info, return nullptr; } BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoState* reference_state = nullptr; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { reference_state = &bta_av_source_state_; } else { reference_state = &bta_av_legacy_state_; } BtaAvCoPeer* active_peer = reference_state->getActivePeer(); // if offset is 0, the decremental operation may result in // underflow and OOB access if (ContentProtectEnabled() && (active_peer != nullptr) && Loading Loading @@ -731,12 +758,19 @@ void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle, p_peer->mtu = mtu; } bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) { bool BtaAvCo::SetActivePeer(const RawAddress& peer_address, const uint8_t t_local_sep) { log::info("peer_address={}", ADDRESS_TO_LOGGABLE_STR(peer_address)); std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); BtaAvCoState* reference_state = &bta_av_legacy_state_; BtaAvCoState* reference_state = getStateFromLocalProfile(t_local_sep); if (reference_state == nullptr) { log::warn( "Invalid bta av state for peer_address : {} with local sep as :{}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), t_local_sep); return false; } if (peer_address.IsEmpty()) { // Reset the active peer; reference_state->setActivePeer(nullptr); Loading @@ -759,9 +793,28 @@ bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) { return true; } BtaAvCoState* BtaAvCo::getStateFromLocalProfile(const uint8_t t_local_sep) { if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (t_local_sep == AVDT_TSEP_SRC) { return &bta_av_source_state_; } else if (t_local_sep == AVDT_TSEP_SNK) { return &bta_av_sink_state_; } else { log::warn("Invalid bta av state for local sep type {}", t_local_sep); return nullptr; } } else { return &bta_av_legacy_state_; } } void BtaAvCo::SaveCodec(const uint8_t* new_codec_config) { if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { bta_av_sink_state_.setCodecConfig(new_codec_config); } else { bta_av_legacy_state_.setCodecConfig(new_codec_config); } } void BtaAvCo::GetPeerEncoderParameters( const RawAddress& peer_address, Loading Loading @@ -792,7 +845,9 @@ void BtaAvCo::GetPeerEncoderParameters( const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() { std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { return A2DP_GetEncoderInterface(bta_av_source_state_.getCodecConfig()); } return A2DP_GetEncoderInterface(bta_av_legacy_state_.getCodecConfig()); } Loading Loading @@ -887,7 +942,12 @@ done: // and informing the Media Framework about the change. // Find the peer that is currently open BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoPeer* active_peer; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { active_peer = bta_av_source_state_.getActivePeer(); } else { active_peer = bta_av_legacy_state_.getActivePeer(); } if (p_peer != nullptr && (!restart_output || !success || p_peer != active_peer)) { return ReportSourceCodecState(p_peer); Loading @@ -905,7 +965,12 @@ bool BtaAvCo::SetCodecAudioConfig( log::verbose("codec_audio_config: {}", codec_audio_config.ToString()); // Find the peer that is currently open BtaAvCoPeer* p_peer = bta_av_legacy_state_.getActivePeer(); BtaAvCoPeer* p_peer; if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { p_peer = bta_av_source_state_.getActivePeer(); } else { p_peer = bta_av_legacy_state_.getActivePeer(); } if (p_peer == nullptr) { log::error("no active peer to configure"); return false; Loading Loading @@ -942,7 +1007,7 @@ bool BtaAvCo::SetCodecAudioConfig( } SaveNewCodecConfig(p_peer, result_codec_config, p_sink->num_protect, p_sink->protect_info); p_sink->protect_info, AVDT_TSEP_SRC); p_peer->acceptor = false; log::verbose("call BTA_AvReconfig({})", loghex(p_peer->BtaAvHandle())); Loading @@ -962,6 +1027,10 @@ bool BtaAvCo::SetCodecAudioConfig( int BtaAvCo::GetSourceEncoderEffectiveFrameSize() { std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { return A2DP_GetEecoderEffectiveFrameSize( bta_av_source_state_.getCodecConfig()); } return A2DP_GetEecoderEffectiveFrameSize( bta_av_legacy_state_.getCodecConfig()); } Loading Loading @@ -1022,6 +1091,18 @@ void BtaAvCo::DebugDump(int fd) { a2dp_codecs->debug_codec_dump(fd); } } if (bta_av_source_state_.getActivePeer() != nullptr) { A2dpCodecs* a2dp_codecs = bta_av_source_state_.getActivePeer()->GetCodecs(); if (a2dp_codecs != nullptr) { a2dp_codecs->debug_codec_dump(fd); } } if (bta_av_sink_state_.getActivePeer() != nullptr) { A2dpCodecs* a2dp_codecs = bta_av_sink_state_.getActivePeer()->GetCodecs(); if (a2dp_codecs != nullptr) { a2dp_codecs->debug_codec_dump(fd); } } dprintf(fd, "\nA2DP Peers State:\n"); dprintf( Loading @@ -1029,6 +1110,16 @@ void BtaAvCo::DebugDump(int fd) { (bta_av_legacy_state_.getActivePeer() != nullptr) ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_legacy_state_.getActivePeer()->addr) : "null"); dprintf( fd, " Source: active peer: %s\n", (bta_av_source_state_.getActivePeer() != nullptr) ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_source_state_.getActivePeer()->addr) : "null"); dprintf( fd, " Sink: active peer: %s\n", (bta_av_sink_state_.getActivePeer() != nullptr) ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_sink_state_.getActivePeer()->addr) : "null"); for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) { const BtaAvCoPeer& peer = peer_cache_->peers_[i]; Loading Loading @@ -1108,7 +1199,7 @@ BtaAvCoSep* BtaAvCo::SelectProviderCodecConfiguration( p_peer->GetCodecs()->setCurrentCodecConfig(codec_config); p_peer->p_sink = p_sink; SaveNewCodecConfig(p_peer, provider_codec_config.codec_config, p_sink->num_protect, p_sink->protect_info); p_sink->num_protect, p_sink->protect_info, AVDT_TSEP_SRC); return p_sink; } Loading Loading @@ -1216,7 +1307,7 @@ const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection( p_peer->p_sink = p_sink; SaveNewCodecConfig(p_peer, new_codec_config, p_sink->num_protect, p_sink->protect_info); p_sink->protect_info, AVDT_TSEP_SRC); return p_sink; } Loading @@ -1243,7 +1334,7 @@ const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection( p_peer->p_source = p_source; SaveNewCodecConfig(p_peer, new_codec_config, p_source->num_protect, p_source->protect_info); p_source->protect_info, AVDT_TSEP_SNK); return p_source; } Loading Loading @@ -1318,12 +1409,20 @@ bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config, void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, uint8_t num_protect, const uint8_t* p_protect_info) { const uint8_t* p_protect_info, const uint8_t t_local_sep) { log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); log::verbose("codec: {}", A2DP_CodecInfoString(new_codec_config)); std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_); bta_av_legacy_state_.setCodecConfig(new_codec_config); BtaAvCoState* reference_state = getStateFromLocalProfile(t_local_sep); if (reference_state == nullptr) { log::warn( "Invalid bta av state for peer_address : {} with local sep as :{}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), t_local_sep); return; } reference_state->setCodecConfig(new_codec_config); memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE); if (ContentProtectEnabled()) { Loading @@ -1333,11 +1432,29 @@ void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer, } } BtaAvCoState* BtaAvCo::getStateFromPeer(const BtaAvCoPeer* p_peer) { if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SINK) { return &bta_av_source_state_; } else if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) { return &bta_av_sink_state_; } else { log::warn("Invalid bta av state for peer_address : {} with uuid as :{}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), p_peer->uuid_to_connect); return nullptr; } } else { return &bta_av_legacy_state_; } } bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, uint8_t num_protect, const uint8_t* p_protect_info, bool* p_restart_output) { bool* p_restart_output, const uint8_t t_local_sep) { uint8_t result_codec_config[AVDT_CODEC_SIZE]; bool restart_input = false; bool restart_output = false; Loading Loading @@ -1376,8 +1493,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, *p_restart_output = true; p_peer->p_sink = p_sink; SaveNewCodecConfig(p_peer, result_codec_config, num_protect, p_protect_info); SaveNewCodecConfig(p_peer, result_codec_config, num_protect, p_protect_info, t_local_sep); } if (restart_input || config_updated) { Loading Loading @@ -1569,7 +1686,15 @@ void bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle, } bool bta_av_co_set_active_peer(const RawAddress& peer_address) { return bta_av_co_cb.SetActivePeer(peer_address); return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_INVALID); } bool bta_av_co_set_active_sink_peer(const RawAddress& peer_address) { return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_SNK); } bool bta_av_co_set_active_source_peer(const RawAddress& peer_address) { return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_SRC); } void bta_av_co_save_codec(const uint8_t* new_codec_config) { Loading
system/btif/include/bta_av_co.h +25 −4 Original line number Diff line number Diff line Loading @@ -288,9 +288,10 @@ class BtaAvCo { * Set the active peer. * * @param peer_address the peer address * @param t_local_sep update the active peer for the profile type. * @return true on success, otherwise false */ bool SetActivePeer(const RawAddress& peer_address); bool SetActivePeer(const RawAddress& peer_address, const uint8_t t_local_sep); /** * Save the reconfig codec Loading Loading @@ -434,9 +435,12 @@ class BtaAvCo { * @param new_codec_config the new codec configuration to use * @param num_protect the number of content protection elements * @param p_protect_info the content protection info to use * @param t_local_sep the profile for which the codec config needs to be * saved. */ void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, uint8_t num_protect, const uint8_t* p_protect_info); uint8_t num_protect, const uint8_t* p_protect_info, const uint8_t t_local_sep); /** * Set the Over-The-Air preferred codec configuration. Loading @@ -455,11 +459,12 @@ class BtaAvCo { * @param p_restart_output if there is a change in the encoder configuration * that requires restarting of the A2DP connection, flag |p_restart_output| * is set to true. * @param t_local_sep the profile for which ota config needs to be set. * @return true on success, otherwise false */ bool SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, uint8_t num_protect, const uint8_t* p_protect_info, bool* p_restart_output); bool* p_restart_output, const uint8_t t_local_sep); /** * Update all selectable Source codecs with the corresponding codec Loading Loading @@ -540,9 +545,25 @@ class BtaAvCo { const ::bluetooth::audio::a2dp::provider::a2dp_configuration& provider_codec_config); /** * Returns the state that needs to be accessed. * @param p_peer peer address. * @return state of the profile. */ BtaAvCoState* getStateFromPeer(const BtaAvCoPeer* p_peer); /** * Returns the state based on the local profile of the stack. * @param t_local_sep local sep type * @return state of the profile. */ BtaAvCoState* getStateFromLocalProfile(const uint8_t t_local_sep); bool ContentProtectEnabled() const { return content_protect_enabled_; } const bool content_protect_enabled_; // True if Content Protect is enabled uint8_t content_protect_flag_; // Content Protect flag BtaAvCoState bta_av_legacy_state_; BtaAvCoState bta_av_legacy_state_; // Legacy state BtaAvCoState bta_av_source_state_; // Source profile state BtaAvCoState bta_av_sink_state_; // Sink profile state };
system/btif/include/btif_av_co.h +14 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,20 @@ // Returns true on success, otherwise false. bool bta_av_co_set_active_peer(const RawAddress& peer_addr); /** * Sets the active peer within the sink profile of the bta av co instance. * @param peer_address peer address of the remote device. * @return true on success, otherwise false. */ bool bta_av_co_set_active_sink_peer(const RawAddress& peer_address); /** * Sets the active peer within the sink profile of the bta av co instance. * @param peer_address peer address of the remote device. * @return true on success, otherwise false. */ bool bta_av_co_set_active_source_peer(const RawAddress& peer_address); void bta_av_co_save_codec(const uint8_t* new_codec_config); // Gets the A2DP peer parameters that are used to initialize the encoder. Loading
system/btif/src/btif_a2dp_sink.cc +15 −6 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "btif/include/btif_a2dp_sink.h" #include <android_bluetooth_flags.h> #include <base/functional/bind.h> #include <base/logging.h> #include <bluetooth/log.h> Loading Loading @@ -258,13 +259,21 @@ bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address, if (!old_peer_address.IsEmpty()) { btif_a2dp_sink_end_session(old_peer_address); } if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (!bta_av_co_set_active_sink_peer(new_peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_STR(new_peer_address)); peer_ready_promise.set_value(); return false; } } else { if (!bta_av_co_set_active_peer(new_peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_STR(new_peer_address)); peer_ready_promise.set_value(); return false; } } if (old_peer_address.IsEmpty()) { btif_a2dp_sink_startup(); Loading
system/btif/src/btif_a2dp_source.cc +12 −5 Original line number Diff line number Diff line Loading @@ -578,12 +578,19 @@ static void btif_a2dp_source_setup_codec_delayed( tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; bta_av_co_get_peer_params(peer_address, &peer_params); if (IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) { if (!bta_av_co_set_active_source_peer(peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } } else { if (!bta_av_co_set_active_peer(peer_address)) { log::error("Cannot stream audio: cannot set active peer to {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } } btif_a2dp_source_cb.encoder_interface = bta_av_co_get_encoder_interface(); if (btif_a2dp_source_cb.encoder_interface == nullptr) { log::error("Cannot stream audio: no source encoder interface"); Loading