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

Commit 93375ecb authored by Ugo Yu's avatar Ugo Yu Committed by Cheney Ni
Browse files

Do not config A2DP codec priorities before retrieving all capabilities

* In current A2DP design, if Java A2DP service disabled optional
  codec and invoke native SetCodecUserConfig() while our get codec
  capabilities process is not finished, stack would raise SBC
  priority to 1000000 without notifying the remote device. This
  behavior would cause phone and the remote headset using different
  codec while A2DP streaming and lead to no sound problem.
* We should always check the codec capabilities status before changing
  the codec priority.

Bug: 124254557
Test: manual

Change-Id: I19693ecdd581836829c15ae37d579a4cb3ac0200
parent ad4eca7b
Loading
Loading
Loading
Loading
+38 −40
Original line number Diff line number Diff line
@@ -1476,14 +1476,22 @@ bool BtaAvCo::SetCodecUserConfig(
  bool config_updated = false;
  bool success = true;

  APPL_TRACE_DEBUG("%s: peer_address=%s codec_user_config=%s", __func__,
                   peer_address.ToString().c_str(),
                   codec_user_config.ToString().c_str());
  VLOG(1) << __func__ << ": peer_address=" << peer_address.ToString()
          << " codec_user_config=" << codec_user_config.ToString();

  BtaAvCoPeer* p_peer = FindPeer(peer_address);
  if (p_peer == nullptr) {
    APPL_TRACE_ERROR("%s: cannot find peer %s to configure", __func__,
                     peer_address.ToString().c_str());
    LOG(ERROR) << __func__ << ": cannot find peer " << peer_address.ToString()
               << " to configure";
    success = false;
    goto done;
  }

  // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
  if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
      (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
    LOG(WARNING) << __func__ << ": peer " << p_peer->addr.ToString()
                 << " : not all peer's capabilities have been retrieved";
    success = false;
    goto done;
  }
@@ -1496,10 +1504,9 @@ bool BtaAvCo::SetCodecUserConfig(
    p_sink = p_peer->p_sink;
  }
  if (p_sink == nullptr) {
    APPL_TRACE_ERROR(
        "%s: peer %s : cannot find peer SEP to configure for codec type %d",
        __func__, p_peer->addr.ToString().c_str(),
        codec_user_config.codec_type);
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
               << " : cannot find peer SEP to configure for codec type "
               << codec_user_config.codec_type;
    success = false;
    goto done;
  }
@@ -1522,24 +1529,15 @@ bool BtaAvCo::SetCodecUserConfig(

    p_sink = SelectSourceCodec(p_peer);
    if (p_sink == nullptr) {
      APPL_TRACE_ERROR("%s: peer %s : cannot set up codec for the peer SINK",
                       __func__, p_peer->addr.ToString().c_str());
      success = false;
      goto done;
    }
    // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
    if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
        (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
      APPL_TRACE_WARNING(
          "%s: peer %s : not all peer's capabilities have been retrieved",
          __func__, p_peer->addr.ToString().c_str());
      LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
                 << " : cannot set up codec for the peer SINK";
      success = false;
      goto done;
    }

    p_peer->acceptor = false;
    APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x)", __func__,
                     p_peer->BtaAvHandle());
    VLOG(1) << __func__ << ": call BTA_AvReconfig("
            << loghex(p_peer->BtaAvHandle()) << ")";
    BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
                   p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
  }
@@ -1563,21 +1561,29 @@ bool BtaAvCo::SetCodecAudioConfig(
  bool restart_output = false;
  bool config_updated = false;

  APPL_TRACE_DEBUG("%s: codec_audio_config: %s", __func__,
                   codec_audio_config.ToString().c_str());
  VLOG(1) << __func__
          << ": codec_audio_config: " << codec_audio_config.ToString();

  // Find the peer that is currently open
  BtaAvCoPeer* p_peer = active_peer_;
  if (p_peer == nullptr) {
    APPL_TRACE_ERROR("%s: no active peer to configure", __func__);
    LOG(ERROR) << __func__ << ": no active peer to configure";
    return false;
  }

  // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
  if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
      (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
    LOG(WARNING) << __func__ << ": peer " << p_peer->addr.ToString()
                 << " : not all peer's capabilities have been retrieved";
    return false;
  }

  // Use the current sink codec
  const BtaAvCoSep* p_sink = p_peer->p_sink;
  if (p_sink == nullptr) {
    APPL_TRACE_ERROR("%s: peer %s : cannot find peer SEP to configure",
                     __func__, p_peer->addr.ToString().c_str());
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
               << " : cannot find peer SEP to configure";
    return false;
  }

@@ -1598,20 +1604,12 @@ bool BtaAvCo::SetCodecAudioConfig(
    SaveNewCodecConfig(p_peer, result_codec_config, p_sink->num_protect,
                       p_sink->protect_info);

    // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
    if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
        (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
      APPL_TRACE_WARNING(
          "%s: peer %s : not all peer's capabilities have been retrieved",
          __func__, p_peer->addr.ToString().c_str());
    } else {
    p_peer->acceptor = false;
      APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x)", __func__,
                       p_peer->BtaAvHandle());
    VLOG(1) << __func__ << ": call BTA_AvReconfig("
            << loghex(p_peer->BtaAvHandle()) << ")";
    BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
                   p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
  }
  }

  if (config_updated) {
    // NOTE: Currently, the input is restarted by sending an upcall