Loading system/btif/co/bta_av_co.cc +29 −2 Original line number Diff line number Diff line Loading @@ -958,8 +958,9 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { return A2DP_FAIL; } APPL_TRACE_DEBUG("%s: last Sink codec reached for peer %s", __func__, p_peer->addr.ToString().c_str()); APPL_TRACE_DEBUG("%s: last Sink codec reached for peer %s (local %s)", __func__, p_peer->addr.ToString().c_str(), p_peer->acceptor ? "acceptor" : "initiator"); // Select the Source codec const BtaAvCoSep* p_sink = nullptr; Loading @@ -977,6 +978,32 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( return A2DP_FAIL; } } else { if (btif_av_peer_prefers_mandatory_codec(p_peer->addr)) { // Apply user preferred codec directly before first codec selected. p_sink = FindPeerSink(p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC); if (p_sink != nullptr) { APPL_TRACE_API("%s: mandatory codec preferred for peer %s", __func__, p_peer->addr.ToString().c_str()); btav_a2dp_codec_config_t high_priority_mandatory{ .codec_type = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, .codec_priority = BTAV_A2DP_CODEC_PRIORITY_HIGHEST, // Using default settings for those untouched fields }; uint8_t result_codec_config[AVDT_CODEC_SIZE]; bool restart_input = false; bool restart_output = false; bool config_updated = false; tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; GetPeerEncoderParameters(p_peer->addr, &peer_params); p_peer->GetCodecs()->setCodecUserConfig( high_priority_mandatory, &peer_params, p_sink->codec_caps, result_codec_config, &restart_input, &restart_output, &config_updated); } else { APPL_TRACE_WARNING("%s: mandatory codec not found for peer %s", __func__, p_peer->addr.ToString().c_str()); } } p_sink = SelectSourceCodec(p_peer); if (p_sink == nullptr) { APPL_TRACE_ERROR("%s: cannot set up codec for peer %s", __func__, Loading system/btif/include/btif_av.h +8 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,14 @@ bool btif_av_is_peer_edr(const RawAddress& peer_address); */ bool btif_av_peer_supports_3mbps(const RawAddress& peer_address); /** * Check whether the mandatory codec is more preferred for this peer. * * @param peer_address the target peer address * @return true if optional codecs are not preferred to be used */ bool btif_av_peer_prefers_mandatory_codec(const RawAddress& peer_address); /** * Report A2DP Source Codec State for a peer. * Loading system/btif/src/btif_av.cc +55 −4 Original line number Diff line number Diff line Loading @@ -278,13 +278,18 @@ class BtifAvPeer { bool IsConnected() const; bool IsStreaming() const; bool IsInSilenceMode() const { return is_silenced_; }; bool IsInSilenceMode() const { return is_silenced_; } void SetSilence(bool silence) { is_silenced_ = silence; }; void SetSilence(bool silence) { is_silenced_ = silence; } // AVDTP delay reporting in 1/10 milliseconds void SetDelayReport(uint16_t delay) { delay_report_ = delay; }; uint16_t GetDelayReport() const { return delay_report_; }; void SetDelayReport(uint16_t delay) { delay_report_ = delay; } uint16_t GetDelayReport() const { return delay_report_; } void SetMandatoryCodecPreferred(bool preferred) { mandatory_codec_preferred_ = preferred; } bool IsMandatoryCodecPreferred() const { return mandatory_codec_preferred_; } /** * Check whether any of the flags specified by the bitlags mask is set. Loading Loading @@ -335,6 +340,7 @@ class BtifAvPeer { bool self_initiated_connection_; bool is_silenced_; uint16_t delay_report_; bool mandatory_codec_preferred_ = false; }; class BtifAvSource { Loading Loading @@ -682,6 +688,8 @@ static void btif_report_audio_state(const RawAddress& peer_address, btav_audio_state_t state); static void btif_av_report_sink_audio_config_state( const RawAddress& peer_address, int sample_rate, int channel_count); static void btif_av_query_mandatory_codec_priority( const RawAddress& peer_address); static void btif_av_source_initiate_av_open_timer_timeout(void* data); static void btif_av_sink_initiate_av_open_timer_timeout(void* data); static void bta_av_sink_media_callback(const RawAddress& peer_address, Loading Loading @@ -1459,6 +1467,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { } break; } btif_av_query_mandatory_codec_priority(peer_.PeerAddress()); BTA_AvOpen(peer_.PeerAddress(), peer_.BtaHandle(), true, BTA_SEC_AUTHENTICATE, peer_.LocalUuidServiceClass()); peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateOpening); Loading Loading @@ -2438,6 +2447,36 @@ static void btif_av_report_sink_audio_config_state( } } /** * Call out to JNI / JAVA layers to retrieve whether the mandatory codec is more * preferred than others. * * @param peer_address the peer address */ static void btif_av_query_mandatory_codec_priority( const RawAddress& peer_address) { auto query_priority = [](const RawAddress& peer_address) { auto apply_priority = [](const RawAddress& peer_address, bool preferred) { BtifAvPeer* peer = btif_av_source_find_peer(peer_address); if (peer == nullptr) { BTIF_TRACE_WARNING( "btif_av_query_mandatory_codec_priority: peer is null"); return; } peer->SetMandatoryCodecPreferred(preferred); }; bool preferred = btif_av_source.Callbacks()->mandatory_codec_preferred_cb(peer_address); if (preferred) { do_in_main_thread( FROM_HERE, base::BindOnce(apply_priority, peer_address, preferred)); } }; if (btif_av_source.Enabled()) { do_in_jni_thread(FROM_HERE, base::BindOnce(query_priority, peer_address)); } } /** * Process BTIF or BTA AV or BTA AVRCP events. The processing is done on the * JNI thread. Loading Loading @@ -3255,6 +3294,16 @@ bool btif_av_peer_supports_3mbps(const RawAddress& peer_address) { return (is_connected && is3mbps); } bool btif_av_peer_prefers_mandatory_codec(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { BTIF_TRACE_WARNING("%s: No peer found for peer_address=%s", __func__, peer_address.ToString().c_str()); return false; } return peer->IsMandatoryCodecPreferred(); } void btif_av_acl_disconnected(const RawAddress& peer_address) { // Inform the application that ACL is disconnected and move to idle state LOG_INFO(LOG_TAG, "%s: Peer %s : ACL Disconnected", __func__, Loading Loading @@ -3308,6 +3357,8 @@ static void btif_debug_av_peer_dump(int fd, const BtifAvPeer& peer) { dprintf(fd, " Self Initiated Connection: %s\n", peer.SelfInitiatedConnection() ? "true" : "false"); dprintf(fd, " Delay Reporting: %u\n", peer.GetDelayReport()); dprintf(fd, " Codec Preferred: %s\n", peer.IsMandatoryCodecPreferred() ? "Mandatory" : "Optional"); } static void btif_debug_av_source_dump(int fd) { Loading system/include/hardware/bt_av.h +8 −0 Original line number Diff line number Diff line Loading @@ -266,6 +266,13 @@ typedef void (*btav_audio_sink_config_callback)(const RawAddress& bd_addr, uint32_t sample_rate, uint8_t channel_count); /** Callback for querying whether the mandatory codec is more preferred. * Used only for the A2DP Source interface. * Return true if optional codecs are not preferred. */ typedef bool (*btav_mandatory_codec_preferred_callback)( const RawAddress& bd_addr); /** BT-AV A2DP Source callback structure. */ typedef struct { /** set to sizeof(btav_source_callbacks_t) */ Loading @@ -273,6 +280,7 @@ typedef struct { btav_connection_state_callback connection_state_cb; btav_audio_state_callback audio_state_cb; btav_audio_source_config_callback audio_config_cb; btav_mandatory_codec_preferred_callback mandatory_codec_preferred_cb; } btav_source_callbacks_t; /** BT-AV A2DP Sink callback structure. */ Loading Loading
system/btif/co/bta_av_co.cc +29 −2 Original line number Diff line number Diff line Loading @@ -958,8 +958,9 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { return A2DP_FAIL; } APPL_TRACE_DEBUG("%s: last Sink codec reached for peer %s", __func__, p_peer->addr.ToString().c_str()); APPL_TRACE_DEBUG("%s: last Sink codec reached for peer %s (local %s)", __func__, p_peer->addr.ToString().c_str(), p_peer->acceptor ? "acceptor" : "initiator"); // Select the Source codec const BtaAvCoSep* p_sink = nullptr; Loading @@ -977,6 +978,32 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( return A2DP_FAIL; } } else { if (btif_av_peer_prefers_mandatory_codec(p_peer->addr)) { // Apply user preferred codec directly before first codec selected. p_sink = FindPeerSink(p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC); if (p_sink != nullptr) { APPL_TRACE_API("%s: mandatory codec preferred for peer %s", __func__, p_peer->addr.ToString().c_str()); btav_a2dp_codec_config_t high_priority_mandatory{ .codec_type = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, .codec_priority = BTAV_A2DP_CODEC_PRIORITY_HIGHEST, // Using default settings for those untouched fields }; uint8_t result_codec_config[AVDT_CODEC_SIZE]; bool restart_input = false; bool restart_output = false; bool config_updated = false; tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; GetPeerEncoderParameters(p_peer->addr, &peer_params); p_peer->GetCodecs()->setCodecUserConfig( high_priority_mandatory, &peer_params, p_sink->codec_caps, result_codec_config, &restart_input, &restart_output, &config_updated); } else { APPL_TRACE_WARNING("%s: mandatory codec not found for peer %s", __func__, p_peer->addr.ToString().c_str()); } } p_sink = SelectSourceCodec(p_peer); if (p_sink == nullptr) { APPL_TRACE_ERROR("%s: cannot set up codec for peer %s", __func__, Loading
system/btif/include/btif_av.h +8 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,14 @@ bool btif_av_is_peer_edr(const RawAddress& peer_address); */ bool btif_av_peer_supports_3mbps(const RawAddress& peer_address); /** * Check whether the mandatory codec is more preferred for this peer. * * @param peer_address the target peer address * @return true if optional codecs are not preferred to be used */ bool btif_av_peer_prefers_mandatory_codec(const RawAddress& peer_address); /** * Report A2DP Source Codec State for a peer. * Loading
system/btif/src/btif_av.cc +55 −4 Original line number Diff line number Diff line Loading @@ -278,13 +278,18 @@ class BtifAvPeer { bool IsConnected() const; bool IsStreaming() const; bool IsInSilenceMode() const { return is_silenced_; }; bool IsInSilenceMode() const { return is_silenced_; } void SetSilence(bool silence) { is_silenced_ = silence; }; void SetSilence(bool silence) { is_silenced_ = silence; } // AVDTP delay reporting in 1/10 milliseconds void SetDelayReport(uint16_t delay) { delay_report_ = delay; }; uint16_t GetDelayReport() const { return delay_report_; }; void SetDelayReport(uint16_t delay) { delay_report_ = delay; } uint16_t GetDelayReport() const { return delay_report_; } void SetMandatoryCodecPreferred(bool preferred) { mandatory_codec_preferred_ = preferred; } bool IsMandatoryCodecPreferred() const { return mandatory_codec_preferred_; } /** * Check whether any of the flags specified by the bitlags mask is set. Loading Loading @@ -335,6 +340,7 @@ class BtifAvPeer { bool self_initiated_connection_; bool is_silenced_; uint16_t delay_report_; bool mandatory_codec_preferred_ = false; }; class BtifAvSource { Loading Loading @@ -682,6 +688,8 @@ static void btif_report_audio_state(const RawAddress& peer_address, btav_audio_state_t state); static void btif_av_report_sink_audio_config_state( const RawAddress& peer_address, int sample_rate, int channel_count); static void btif_av_query_mandatory_codec_priority( const RawAddress& peer_address); static void btif_av_source_initiate_av_open_timer_timeout(void* data); static void btif_av_sink_initiate_av_open_timer_timeout(void* data); static void bta_av_sink_media_callback(const RawAddress& peer_address, Loading Loading @@ -1459,6 +1467,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { } break; } btif_av_query_mandatory_codec_priority(peer_.PeerAddress()); BTA_AvOpen(peer_.PeerAddress(), peer_.BtaHandle(), true, BTA_SEC_AUTHENTICATE, peer_.LocalUuidServiceClass()); peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateOpening); Loading Loading @@ -2438,6 +2447,36 @@ static void btif_av_report_sink_audio_config_state( } } /** * Call out to JNI / JAVA layers to retrieve whether the mandatory codec is more * preferred than others. * * @param peer_address the peer address */ static void btif_av_query_mandatory_codec_priority( const RawAddress& peer_address) { auto query_priority = [](const RawAddress& peer_address) { auto apply_priority = [](const RawAddress& peer_address, bool preferred) { BtifAvPeer* peer = btif_av_source_find_peer(peer_address); if (peer == nullptr) { BTIF_TRACE_WARNING( "btif_av_query_mandatory_codec_priority: peer is null"); return; } peer->SetMandatoryCodecPreferred(preferred); }; bool preferred = btif_av_source.Callbacks()->mandatory_codec_preferred_cb(peer_address); if (preferred) { do_in_main_thread( FROM_HERE, base::BindOnce(apply_priority, peer_address, preferred)); } }; if (btif_av_source.Enabled()) { do_in_jni_thread(FROM_HERE, base::BindOnce(query_priority, peer_address)); } } /** * Process BTIF or BTA AV or BTA AVRCP events. The processing is done on the * JNI thread. Loading Loading @@ -3255,6 +3294,16 @@ bool btif_av_peer_supports_3mbps(const RawAddress& peer_address) { return (is_connected && is3mbps); } bool btif_av_peer_prefers_mandatory_codec(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { BTIF_TRACE_WARNING("%s: No peer found for peer_address=%s", __func__, peer_address.ToString().c_str()); return false; } return peer->IsMandatoryCodecPreferred(); } void btif_av_acl_disconnected(const RawAddress& peer_address) { // Inform the application that ACL is disconnected and move to idle state LOG_INFO(LOG_TAG, "%s: Peer %s : ACL Disconnected", __func__, Loading Loading @@ -3308,6 +3357,8 @@ static void btif_debug_av_peer_dump(int fd, const BtifAvPeer& peer) { dprintf(fd, " Self Initiated Connection: %s\n", peer.SelfInitiatedConnection() ? "true" : "false"); dprintf(fd, " Delay Reporting: %u\n", peer.GetDelayReport()); dprintf(fd, " Codec Preferred: %s\n", peer.IsMandatoryCodecPreferred() ? "Mandatory" : "Optional"); } static void btif_debug_av_source_dump(int fd) { Loading
system/include/hardware/bt_av.h +8 −0 Original line number Diff line number Diff line Loading @@ -266,6 +266,13 @@ typedef void (*btav_audio_sink_config_callback)(const RawAddress& bd_addr, uint32_t sample_rate, uint8_t channel_count); /** Callback for querying whether the mandatory codec is more preferred. * Used only for the A2DP Source interface. * Return true if optional codecs are not preferred. */ typedef bool (*btav_mandatory_codec_preferred_callback)( const RawAddress& bd_addr); /** BT-AV A2DP Source callback structure. */ typedef struct { /** set to sizeof(btav_source_callbacks_t) */ Loading @@ -273,6 +280,7 @@ typedef struct { btav_connection_state_callback connection_state_cb; btav_audio_state_callback audio_state_cb; btav_audio_source_config_callback audio_config_cb; btav_mandatory_codec_preferred_callback mandatory_codec_preferred_cb; } btav_source_callbacks_t; /** BT-AV A2DP Sink callback structure. */ Loading