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

Commit a40f1c38 authored by Cheney Ni's avatar Cheney Ni
Browse files

A2DP: Report codec configurations after retrieved all capabilities

When we are an A2DP source, the audio framework needs the codec report
to restart our input, and we also use this information to determinate
whether a user codec preference is acceptable or not. We
unconditionally send the event before. However, if we were late to
retrieve all capabilities from an active peer, there was no reports to
upper layer. Now there are report events by following conditions:

* The stack (AVDTP SRC) gets all codec capabilities of a sink.
  Before this change, there was only a report when we were the initiator
  to do AVDTP_SetConfig by BtaAvCo::SelectSourceCodec(), and now we
  send the report after retrieved remote's all capabilities.
* Get the codec configuration from OTA when remote does AVDTP_SetConfig.
* The stack is (re)starting a new audio HAL session for A2DP, and we use
  this event to inform the Media Framework about the change of selected
  codec. This happens when changing the active peer / changing the codec
  configuration of active peer.
* User changes the codec config of a none active peer.
* Failed to apply the user / audio codec preference.

This CL also touched some logging message to be C++ style.

Bug: 139338503
Test: 1. manually reconnected from remote and local.
      2. changing the selected codec configuration.
Change-Id: Ia15d03c500b3fd961be41afd9e40999a161e21ef
parent d91c695b
Loading
Loading
Loading
Loading
+43 −46
Original line number Diff line number Diff line
@@ -1005,6 +1005,11 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
    memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
  }

  // report this peer selectable codecs after retrieved all its capabilities.
  LOG(INFO) << __func__ << ": retrieved " << +p_peer->num_rx_sinks
            << " capabilities from peer " << p_peer->addr;
  ReportSourceCodecState(p_peer);

  return A2DP_SUCCESS;
}

@@ -1402,8 +1407,7 @@ void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
}

bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {
  APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
                   peer_address.ToString().c_str());
  VLOG(1) << __func__ << ": peer_address=" << peer_address;

  std::lock_guard<std::recursive_mutex> lock(codec_lock_);

@@ -1422,8 +1426,8 @@ bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {

  active_peer_ = p_peer;
  memcpy(codec_config_, active_peer_->codec_config, AVDT_CODEC_SIZE);
  APPL_TRACE_DEBUG("%s: codec = %s", __func__,
                   A2DP_CodecInfoString(codec_config_).c_str());
  LOG(INFO) << __func__ << ": codec = " << A2DP_CodecInfoString(codec_config_);
  // report the selected codec configuration of this new active peer.
  ReportSourceCodecState(active_peer_);
  return true;
}
@@ -1476,12 +1480,12 @@ bool BtaAvCo::SetCodecUserConfig(
  bool config_updated = false;
  bool success = true;

  VLOG(1) << __func__ << ": peer_address=" << peer_address.ToString()
          << " codec_user_config=" << codec_user_config.ToString();
  VLOG(1) << __func__ << ": peer_address=" << peer_address
          << " codec_user_config={" << codec_user_config.ToString() << "}";

  BtaAvCoPeer* p_peer = FindPeer(peer_address);
  if (p_peer == nullptr) {
    LOG(ERROR) << __func__ << ": cannot find peer " << peer_address.ToString()
    LOG(ERROR) << __func__ << ": cannot find peer " << peer_address
               << " to configure";
    success = false;
    goto done;
@@ -1490,7 +1494,7 @@ bool BtaAvCo::SetCodecUserConfig(
  // 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()
    LOG(WARNING) << __func__ << ": peer " << p_peer->addr
                 << " : not all peer's capabilities have been retrieved";
    success = false;
    goto done;
@@ -1504,7 +1508,7 @@ bool BtaAvCo::SetCodecUserConfig(
    p_sink = p_peer->p_sink;
  }
  if (p_sink == nullptr) {
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr
               << " : cannot find peer SEP to configure for codec type "
               << codec_user_config.codec_type;
    success = false;
@@ -1529,7 +1533,7 @@ bool BtaAvCo::SetCodecUserConfig(

    p_sink = SelectSourceCodec(p_peer);
    if (p_sink == nullptr) {
      LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
      LOG(ERROR) << __func__ << ": peer " << p_peer->addr
                 << " : cannot set up codec for the peer SINK";
      success = false;
      goto done;
@@ -1543,12 +1547,16 @@ bool BtaAvCo::SetCodecUserConfig(
  }

done:
  // NOTE: We unconditionally send the upcall even if there is no change
  // or the user config failed. Thus, the caller would always know whether the
  // request succeeded or failed.
  // We send the upcall if there is no change or the user config failed for
  // current active peer, so the caller would know it failed. If there is no
  // error, the new selected codec configuration would be sent after we are
  // ready to start a new session with the audio HAL.
  // For none active peer, we unconditionally send the upcall, so the caller
  // would always know the result.
  // NOTE: Currently, the input is restarted by sending an upcall
  // and informing the Media Framework about the change.
  if (p_peer != nullptr) {
  if (p_peer != nullptr &&
      (!restart_output || !success || p_peer != active_peer_)) {
    return ReportSourceCodecState(p_peer);
  }

@@ -1574,7 +1582,7 @@ bool BtaAvCo::SetCodecAudioConfig(
  // 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()
    LOG(WARNING) << __func__ << ": peer " << p_peer->addr
                 << " : not all peer's capabilities have been retrieved";
    return false;
  }
@@ -1582,7 +1590,7 @@ bool BtaAvCo::SetCodecAudioConfig(
  // Use the current sink codec
  const BtaAvCoSep* p_sink = p_peer->p_sink;
  if (p_sink == nullptr) {
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr
               << " : cannot find peer SEP to configure";
    return false;
  }
@@ -1613,7 +1621,7 @@ bool BtaAvCo::SetCodecAudioConfig(

  if (config_updated) {
    // NOTE: Currently, the input is restarted by sending an upcall
    // and informing the Media Framework about the change.
    // and informing the Media Framework about the change of selected codec.
    return ReportSourceCodecState(p_peer);
  }

@@ -1625,22 +1633,19 @@ bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) {
  std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities;
  std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities;

  APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
                   p_peer->addr.ToString().c_str());
  VLOG(1) << __func__ << ": peer_address=" << p_peer->addr;
  A2dpCodecs* codecs = p_peer->GetCodecs();
  CHECK(codecs != nullptr);
  if (!codecs->getCodecConfigAndCapabilities(&codec_config,
                                             &codecs_local_capabilities,
                                             &codecs_selectable_capabilities)) {
    APPL_TRACE_WARNING(
        "%s: Peer %s : error reporting audio source codec state: "
        "cannot get codec config and capabilities",
        __func__, p_peer->addr.ToString().c_str());
    LOG(WARNING) << __func__ << ": Peer " << p_peer->addr
                 << " : error reporting audio source codec state: cannot get "
                    "codec config and capabilities";
    return false;
  }
  APPL_TRACE_DEBUG("%s: peer %s codec_config=%s", __func__,
                   p_peer->addr.ToString().c_str(),
                   codec_config.ToString().c_str());
  LOG(INFO) << __func__ << ": peer " << p_peer->addr << " codec_config={"
            << codec_config.ToString() << "}";
  btif_av_report_source_codec_state(p_peer->addr, codec_config,
                                    codecs_local_capabilities,
                                    codecs_selectable_capabilities);
@@ -1747,19 +1752,14 @@ const BtaAvCoSep* BtaAvCo::SelectSourceCodec(BtaAvCoPeer* p_peer) {

  // Select the codec
  for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
    APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
    VLOG(1) << __func__ << ": trying codec " << iter->name();
    p_sink = AttemptSourceCodecSelection(*iter, p_peer);
    if (p_sink != nullptr) {
      APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
      VLOG(1) << __func__ << ": selected codec " << iter->name();
      break;
    }
    APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
    VLOG(1) << __func__ << ": cannot use codec " << iter->name();
  }

  // NOTE: Unconditionally dispatch the event to make sure a callback with
  // the most recent codec info is generated.
  ReportSourceCodecState(p_peer);

  return p_sink;
}

@@ -1999,10 +1999,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
  bool restart_output = false;
  bool config_updated = false;

  APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
                   p_peer->addr.ToString().c_str());
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_ota_codec_config).c_str());
  LOG(INFO) << __func__ << ": peer_address=" << p_peer->addr
            << ", codec: " << A2DP_CodecInfoString(p_ota_codec_config);

  *p_restart_output = false;

@@ -2013,8 +2011,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
    // There are no peer SEPs if we didn't do the discovery procedure yet.
    // We have all the information we need from the peer, so we can
    // proceed with the OTA codec configuration.
    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
               << " : cannot find peer SEP to configure";
    return false;
  }

@@ -2023,15 +2021,14 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
  if (!p_peer->GetCodecs()->setCodecOtaConfig(
          p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
          &restart_output, &config_updated)) {
    APPL_TRACE_ERROR("%s: peer %s : cannot set OTA config", __func__,
                     p_peer->addr.ToString().c_str());
    LOG(ERROR) << __func__ << ": peer " << p_peer->addr
               << " : cannot set OTA config";
    return false;
  }

  if (restart_output) {
    APPL_TRACE_DEBUG("%s: restart output", __func__);
    APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                     A2DP_CodecInfoString(result_codec_config).c_str());
    VLOG(1) << __func__ << ": restart output for codec: "
            << A2DP_CodecInfoString(result_codec_config);

    *p_restart_output = true;
    p_peer->p_sink = p_sink;
@@ -2041,7 +2038,7 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,

  if (restart_input || config_updated) {
    // NOTE: Currently, the input is restarted by sending an upcall
    // and informing the Media Framework about the change.
    // and informing the Media Framework about the change of selected codec.
    ReportSourceCodecState(p_peer);
  }