diff --git a/system/btif/co/bta_av_co.cc b/system/btif/co/bta_av_co.cc
index bcf155df253d4b73649f57d55d32fab5d80f8fa5..f68656584f83bee3cd246276d9237a4c11c537b6 100644
--- a/system/btif/co/bta_av_co.cc
+++ b/system/btif/co/bta_av_co.cc
@@ -35,6 +35,7 @@
 #include "audio_hal_interface/a2dp_encoding.h"
 #include "bta/include/bta_av_api.h"
 #include "bta/include/bta_av_ci.h"
+#include "btif/include/bta_av_co_peer.h"
 #include "btif/include/btif_a2dp_source.h"
 #include "btif/include/btif_av.h"
 #include "device/include/device_iot_config.h"
@@ -52,15 +53,6 @@
 #include "stack/include/bt_uuid16.h"
 #include "types/raw_address.h"
 
-// Macro to retrieve the number of elements in a statically allocated array
-#define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0]))
-
-// Macro to convert BTA AV audio handle to index and vice versa
-#define BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle) \
-  (((bta_av_handle) & (~BTA_AV_CHNL_MSK)) - 1)
-#define BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(index) \
-  (((index) + 1) | BTA_AV_CHNL_AUDIO)
-
 using namespace bluetooth;
 
 // SCMS-T protect info
@@ -68,28 +60,24 @@ const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00};
 
 // Control block instance
 static const bool kContentProtectEnabled = false;
-static BtaAvCo bta_av_co_cb(kContentProtectEnabled);
+static BtaAvCo bta_av_co_cb(kContentProtectEnabled, new BtaAvCoPeerCache());
 
 void BtaAvCo::Init(
     const std::vector<btav_a2dp_codec_config_t>& codec_priorities,
     std::vector<btav_a2dp_codec_info_t>* supported_codecs) {
   log::verbose("");
 
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   // Reset the control block
   Reset();
-  codec_priorities_ = codec_priorities;
-
-  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
-    BtaAvCoPeer* p_peer = &peers_[i];
-    p_peer->Init(codec_priorities);
-  }
+  peer_cache_->Init(codec_priorities, supported_codecs);
 
   // Gather the supported codecs from the first peer context;
   // all contexes should be identical.
   supported_codecs->clear();
-  for (auto* codec_config : peers_[0].GetCodecs()->orderedSourceCodecs()) {
+  for (auto* codec_config :
+       peer_cache_->peers_[0].GetCodecs()->orderedSourceCodecs()) {
     auto& codec_info = supported_codecs->emplace_back();
     codec_info.codec_type = codec_config->codecIndex();
     codec_info.codec_id = codec_config->codecId();
@@ -98,7 +86,6 @@ void BtaAvCo::Init(
 }
 
 void BtaAvCo::Reset() {
-  codec_priorities_.clear();
   active_peer_ = nullptr;
   content_protect_flag_ = 0;
   memset(codec_config_, 0, sizeof(codec_config_));
@@ -109,17 +96,13 @@ void BtaAvCo::Reset() {
     SetContentProtectFlag(AVDT_CP_SCMS_COPY_FREE);
   }
 
-  // Reset the peers and initialize the handles
-  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
-    BtaAvCoPeer* p_peer = &peers_[i];
-    p_peer->Reset(BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(i));
-  }
+  peer_cache_->Reset();
 }
 
 bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) {
   // All peer state is initialized with the same local codec config,
   // hence we check only the first peer.
-  A2dpCodecs* codecs = peers_[0].GetCodecs();
+  A2dpCodecs* codecs = peer_cache_->peers_[0].GetCodecs();
   if (codecs == nullptr) {
     log::error("Peer codecs is set to null");
     return false;
@@ -128,7 +111,7 @@ bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) {
 }
 
 A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() {
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   if (active_peer_ == nullptr || active_peer_->GetCodecs() == nullptr) {
     return nullptr;
@@ -137,69 +120,15 @@ A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() {
 }
 
 A2dpCodecConfig* BtaAvCo::GetPeerCurrentCodec(const RawAddress& peer_address) {
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
-  BtaAvCoPeer* peer = FindPeer(peer_address);
+  BtaAvCoPeer* peer = peer_cache_->FindPeer(peer_address);
   if (peer == nullptr || peer->GetCodecs() == nullptr) {
     return nullptr;
   }
   return peer->GetCodecs()->getCurrentCodecConfig();
 }
 
-BtaAvCoPeer* BtaAvCo::FindPeer(const RawAddress& peer_address) {
-  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
-    BtaAvCoPeer* p_peer = &peers_[i];
-    if (p_peer->addr == peer_address) {
-      return p_peer;
-    }
-  }
-  return nullptr;
-}
-
-BtaAvCoPeer* BtaAvCo::FindPeer(tBTA_AV_HNDL bta_av_handle) {
-  uint8_t index;
-
-  index = BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle);
-
-  log::verbose("bta_av_handle = 0x{:x} index = {}", bta_av_handle, index);
-
-  // Sanity check
-  if (index >= BTA_AV_CO_NUM_ELEMENTS(peers_)) {
-    log::error("peer index {} for BTA AV handle 0x{:x} is out of bounds", index,
-               bta_av_handle);
-    return nullptr;
-  }
-
-  return &peers_[index];
-}
-
-BtaAvCoPeer* BtaAvCo::FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
-                                        const RawAddress& peer_address) {
-  log::verbose("peer {} bta_av_handle = 0x{:x}",
-               ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle);
-
-  BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
-  if (p_peer == nullptr) {
-    log::error("peer entry for BTA AV handle 0x{:x} peer {} not found",
-               bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
-    return nullptr;
-  }
-
-  log::verbose("peer {} bta_av_handle = 0x{:x} previous address {}",
-               ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle,
-               ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
-  p_peer->addr = peer_address;
-  return p_peer;
-}
-
-uint16_t BtaAvCo::FindPeerUuid(tBTA_AV_HNDL bta_av_handle) {
-  BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
-  if (p_peer == nullptr) {
-    return 0;
-  }
-  return p_peer->uuid_to_connect;
-}
-
 void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
                                      const RawAddress& peer_address,
                                      uint8_t num_seps, uint8_t num_sinks,
@@ -210,7 +139,8 @@ void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
       num_sinks, num_sources);
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -258,7 +188,8 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
   log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info));
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -317,8 +248,9 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
     UpdateAllSelectableSourceCodecs(p_peer);
     if (p_peer->p_sink == nullptr) {
       // Update the selected codec
-      p_peer->p_sink =
-          FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_peer->codec_config));
+      p_peer->p_sink = peer_cache_->FindPeerSink(
+          p_peer, A2DP_SourceCodecIndex(p_peer->codec_config),
+          ContentProtectFlag());
     }
     p_sink = p_peer->p_sink;
     if (p_sink == nullptr) {
@@ -329,7 +261,8 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
   } 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);
+      p_sink = peer_cache_->FindPeerSink(
+          p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, ContentProtectFlag());
       if (p_sink != nullptr) {
         log::verbose("mandatory codec preferred for peer {}",
                      ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
@@ -399,7 +332,7 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
                                            uint8_t* p_sep_info_idx,
                                            uint8_t seid, uint8_t* p_num_protect,
                                            uint8_t* p_protect_info) {
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   log::verbose("peer {} bta_av_handle:0x{:x} codec:{} seid:{}",
                ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle,
@@ -410,7 +343,8 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
   log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info));
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -459,8 +393,9 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
     UpdateAllSelectableSinkCodecs(p_peer);
     if (p_peer->p_source == nullptr) {
       // Update the selected codec
-      p_peer->p_source =
-          FindPeerSource(p_peer, A2DP_SinkCodecIndex(p_peer->codec_config));
+      p_peer->p_source = peer_cache_->FindPeerSource(
+          p_peer, A2DP_SinkCodecIndex(p_peer->codec_config),
+          ContentProtectFlag());
     }
     p_source = p_peer->p_source;
     if (p_source == nullptr) {
@@ -528,7 +463,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
   log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info));
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -551,8 +487,7 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
 
   if (num_protect != 0) {
     if (ContentProtectEnabled()) {
-      if ((num_protect != 1) ||
-          !BtaAvCo::ContentProtectIsScmst(p_protect_info)) {
+      if ((num_protect != 1) || !ContentProtectIsScmst(p_protect_info)) {
         log::error("wrong CP configuration for peer {}",
                    ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
         status = A2DP_BAD_CP_TYPE;
@@ -633,7 +568,8 @@ void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle,
                ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, mtu);
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -655,7 +591,8 @@ void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle,
   btif_av_reset_audio_delay();
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -666,7 +603,7 @@ void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle,
     active_peer_ = nullptr;
   }
   // Mark the peer closed and clean the peer info
-  p_peer->Init(codec_priorities_);
+  p_peer->Init(peer_cache_->codec_priorities_);
 }
 
 void BtaAvCo::ProcessStart(tBTA_AV_HNDL bta_av_handle,
@@ -676,7 +613,8 @@ void BtaAvCo::ProcessStart(tBTA_AV_HNDL bta_av_handle,
                ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle);
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
                bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
@@ -762,7 +700,8 @@ void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
             ADDRESS_TO_LOGGABLE_STR(peer_address), loghex(bta_av_handle), mtu);
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
+  BtaAvCoPeer* p_peer =
+      peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
   if (p_peer == nullptr) {
     log::error("could not find peer entry for bta_av_handle {} peer {}",
                loghex(bta_av_handle), ADDRESS_TO_LOGGABLE_STR(peer_address));
@@ -774,7 +713,7 @@ void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
 bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {
   log::info("peer_address={}", ADDRESS_TO_LOGGABLE_STR(peer_address));
 
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   if (peer_address.IsEmpty()) {
     // Reset the active peer;
@@ -784,7 +723,7 @@ bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {
   }
 
   // Find the peer
-  BtaAvCoPeer* p_peer = FindPeer(peer_address);
+  BtaAvCoPeer* p_peer = peer_cache_->FindPeer(peer_address);
   if (p_peer == nullptr) {
     return false;
   }
@@ -808,11 +747,11 @@ void BtaAvCo::GetPeerEncoderParameters(
   CHECK(p_peer_params != nullptr) << "Peer address "
                                   << ADDRESS_TO_LOGGABLE_STR(peer_address);
 
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   // Compute the MTU
-  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
-    const BtaAvCoPeer* p_peer = &peers_[i];
+  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) {
+    const BtaAvCoPeer* p_peer = &peer_cache_->peers_[i];
     if (!p_peer->opened) continue;
     if (p_peer->addr != peer_address) continue;
     if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu;
@@ -829,7 +768,7 @@ void BtaAvCo::GetPeerEncoderParameters(
 }
 
 const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() {
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   return A2DP_GetEncoderInterface(codec_config_);
 }
@@ -850,7 +789,7 @@ bool BtaAvCo::SetCodecUserConfig(
 
   *p_restart_output = false;
 
-  BtaAvCoPeer* p_peer = FindPeer(peer_address);
+  BtaAvCoPeer* p_peer = peer_cache_->FindPeer(peer_address);
   if (p_peer == nullptr) {
     log::error("cannot find peer {} to configure",
                ADDRESS_TO_LOGGABLE_STR(peer_address));
@@ -869,7 +808,8 @@ bool BtaAvCo::SetCodecUserConfig(
 
   // Find the peer SEP codec to use
   if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
-    p_sink = FindPeerSink(p_peer, codec_user_config.codec_type);
+    p_sink = peer_cache_->FindPeerSink(p_peer, codec_user_config.codec_type,
+                                       ContentProtectFlag());
   } else {
     // Use the current sink codec
     p_sink = p_peer->p_sink;
@@ -994,7 +934,7 @@ bool BtaAvCo::SetCodecAudioConfig(
 }
 
 int BtaAvCo::GetSourceEncoderEffectiveFrameSize() {
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   return A2DP_GetEecoderEffectiveFrameSize(codec_config_);
 }
@@ -1044,7 +984,7 @@ bool BtaAvCo::ReportSinkCodecState(BtaAvCoPeer* p_peer) {
 }
 
 void BtaAvCo::DebugDump(int fd) {
-  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   //
   // Active peer codec-specific stats
@@ -1062,8 +1002,8 @@ void BtaAvCo::DebugDump(int fd) {
               ? ADDRESS_TO_LOGGABLE_CSTR(active_peer_->addr)
               : "null");
 
-  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
-    const BtaAvCoPeer& peer = peers_[i];
+  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) {
+    const BtaAvCoPeer& peer = peer_cache_->peers_[i];
     if (peer.addr.IsEmpty()) {
       continue;
     }
@@ -1085,46 +1025,6 @@ void BtaAvCo::DebugDump(int fd) {
   }
 }
 
-bool BtaAvCo::ContentProtectIsScmst(const uint8_t* p_protect_info) {
-  log::verbose("");
-
-  if (*p_protect_info >= AVDT_CP_LOSC) {
-    uint16_t cp_id;
-    p_protect_info++;
-    STREAM_TO_UINT16(cp_id, p_protect_info);
-    if (cp_id == AVDT_CP_SCMS_T_ID) {
-      log::verbose("SCMS-T found");
-      return true;
-    }
-  }
-  return false;
-}
-
-bool BtaAvCo::AudioProtectHasScmst(uint8_t num_protect,
-                                   const uint8_t* p_protect_info) {
-  log::verbose("");
-  while (num_protect--) {
-    if (BtaAvCo::ContentProtectIsScmst(p_protect_info)) return true;
-    // Move to the next Content Protect schema
-    p_protect_info += *p_protect_info + 1;
-  }
-  log::verbose("SCMS-T not found");
-  return false;
-}
-
-bool BtaAvCo::AudioSepHasContentProtection(const BtaAvCoSep* p_sep) {
-  log::verbose("");
-
-  // Check if content protection is enabled for this stream
-  if (ContentProtectFlag() != AVDT_CP_SCMS_COPY_FREE) {
-    return BtaAvCo::AudioProtectHasScmst(p_sep->num_protect,
-                                         p_sep->protect_info);
-  }
-
-  log::verbose("not required");
-  return true;
-}
-
 std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration>
 BtaAvCo::GetProviderCodecConfiguration(BtaAvCoPeer* p_peer) {
   // Gather peer codec capabilities.
@@ -1158,8 +1058,9 @@ BtaAvCoSep* BtaAvCo::SelectProviderCodecConfiguration(
   log::info("Configuration={}", provider_codec_config.toString());
 
   // Identify the selected sink.
-  auto* p_sink =
-      FindPeerSink(p_peer, provider_codec_config.codec_parameters.codec_type);
+  auto* p_sink = peer_cache_->FindPeerSink(
+      p_peer, provider_codec_config.codec_parameters.codec_type,
+      ContentProtectFlag());
   ASSERT_LOG(p_sink != nullptr, "Unable to find the selected codec config");
 
   // Identify the selected codec.
@@ -1203,7 +1104,8 @@ const BtaAvCoSep* BtaAvCo::SelectSourceCodec(BtaAvCoPeer* p_peer) {
 
     // Find the peer Sink for the codec
     uint8_t new_codec_config[AVDT_CODEC_SIZE];
-    const BtaAvCoSep* p_sink = FindPeerSink(p_peer, iter->codecIndex());
+    const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
+        p_peer, iter->codecIndex(), ContentProtectFlag());
 
     if (p_sink == nullptr) {
       log::verbose("peer Sink for codec {} not found", iter->name());
@@ -1264,59 +1166,6 @@ const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) {
   return p_source;
 }
 
-BtaAvCoSep* BtaAvCo::FindPeerSink(BtaAvCoPeer* p_peer,
-                                  btav_a2dp_codec_index_t codec_index) {
-  if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
-    log::warn("invalid codec index for peer {}",
-              ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
-    return nullptr;
-  }
-
-  // Find the peer Sink for the codec
-  for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
-    BtaAvCoSep* p_sink = &p_peer->sinks[index];
-    btav_a2dp_codec_index_t peer_codec_index =
-        A2DP_SourceCodecIndex(p_sink->codec_caps);
-    if (peer_codec_index != codec_index) {
-      continue;
-    }
-    if (!AudioSepHasContentProtection(p_sink)) {
-      log::verbose("peer Sink for codec {} does not support Content Protection",
-                   A2DP_CodecIndexStr(codec_index));
-      continue;
-    }
-    return p_sink;
-  }
-  return nullptr;
-}
-
-BtaAvCoSep* BtaAvCo::FindPeerSource(BtaAvCoPeer* p_peer,
-                                    btav_a2dp_codec_index_t codec_index) {
-  if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
-    log::warn("invalid codec index for peer {}",
-              ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
-    return nullptr;
-  }
-
-  // Find the peer Source for the codec
-  for (size_t index = 0; index < p_peer->num_sup_sources; index++) {
-    BtaAvCoSep* p_source = &p_peer->sources[index];
-    btav_a2dp_codec_index_t peer_codec_index =
-        A2DP_SinkCodecIndex(p_source->codec_caps);
-    if (peer_codec_index != codec_index) {
-      continue;
-    }
-    if (!AudioSepHasContentProtection(p_source)) {
-      log::verbose(
-          "peer Source for codec {} does not support Content Protection",
-          A2DP_CodecIndexStr(codec_index));
-      continue;
-    }
-    return p_source;
-  }
-  return nullptr;
-}
-
 const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection(
     const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
   uint8_t new_codec_config[AVDT_CODEC_SIZE];
@@ -1324,7 +1173,8 @@ const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection(
   log::verbose("");
 
   // Find the peer Sink for the codec
-  BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex());
+  BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
+      p_peer, codec_config.codecIndex(), ContentProtectFlag());
   if (p_sink == nullptr) {
     log::verbose("peer Sink for codec {} not found", codec_config.name());
     return nullptr;
@@ -1350,7 +1200,8 @@ const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection(
   log::verbose("");
 
   // Find the peer Source for the codec
-  BtaAvCoSep* p_source = FindPeerSource(p_peer, codec_config.codecIndex());
+  BtaAvCoSep* p_source = peer_cache_->FindPeerSource(
+      p_peer, codec_config.codecIndex(), ContentProtectFlag());
   if (p_source == nullptr) {
     log::verbose("peer Source for codec {} not found", codec_config.name());
     return nullptr;
@@ -1387,7 +1238,8 @@ bool BtaAvCo::UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config,
   log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
 
   // Find the peer Sink for the codec
-  const BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex());
+  const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
+      p_peer, codec_config.codecIndex(), ContentProtectFlag());
   if (p_sink == nullptr) {
     // The peer Sink device does not support this codec
     return false;
@@ -1419,8 +1271,8 @@ bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config,
   log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
 
   // Find the peer Source for the codec
-  const BtaAvCoSep* p_source =
-      FindPeerSource(p_peer, codec_config.codecIndex());
+  const BtaAvCoSep* p_source = peer_cache_->FindPeerSource(
+      p_peer, codec_config.codecIndex(), ContentProtectFlag());
   if (p_source == nullptr) {
     // The peer Source device does not support this codec
     return false;
@@ -1442,14 +1294,14 @@ void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer,
   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(codec_lock_);
+  std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
 
   memcpy(codec_config_, new_codec_config, sizeof(codec_config_));
   memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE);
 
   if (ContentProtectEnabled()) {
     // Check if this Sink supports SCMS
-    bool cp_active = BtaAvCo::AudioProtectHasScmst(num_protect, p_protect_info);
+    bool cp_active = AudioProtectHasScmst(num_protect, p_protect_info);
     p_peer->SetContentProtectActive(cp_active);
   }
 }
@@ -1470,8 +1322,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
   *p_restart_output = false;
 
   // Find the peer SEP codec to use
-  const BtaAvCoSep* p_sink =
-      FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_ota_codec_config));
+  const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
+      p_peer, A2DP_SourceCodecIndex(p_ota_codec_config), ContentProtectFlag());
   if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) {
     // 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
@@ -1613,7 +1465,7 @@ tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle,
                                        uint8_t* p_sep_info_idx, uint8_t seid,
                                        uint8_t* p_num_protect,
                                        uint8_t* p_protect_info) {
-  uint16_t peer_uuid = bta_av_co_cb.FindPeerUuid(bta_av_handle);
+  uint16_t peer_uuid = bta_av_co_cb.peer_cache_->FindPeerUuid(bta_av_handle);
 
   log::verbose("peer {} bta_av_handle=0x{:x} peer_uuid=0x{:x}",
                ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle,
@@ -1724,7 +1576,7 @@ int bta_av_co_get_encoder_effective_frame_size() {
 
 btav_a2dp_scmst_info_t bta_av_co_get_scmst_info(
     const RawAddress& peer_address) {
-  BtaAvCoPeer* p_peer = bta_av_co_cb.FindPeer(peer_address);
+  BtaAvCoPeer* p_peer = bta_av_co_cb.peer_cache_->FindPeer(peer_address);
   CHECK(p_peer != nullptr);
   btav_a2dp_scmst_info_t scmst_info{};
   scmst_info.enable_status = BTAV_A2DP_SCMST_DISABLED;
diff --git a/system/btif/co/bta_av_co_peer.cc b/system/btif/co/bta_av_co_peer.cc
index 76e1b41e9d3dca4ff717ac716095a92d64ea244b..3cfbb3b1489adb09bf1d93bbb77df25282c79383 100644
--- a/system/btif/co/bta_av_co_peer.cc
+++ b/system/btif/co/bta_av_co_peer.cc
@@ -15,11 +15,13 @@
  */
 #include "btif/include/bta_av_co_peer.h"
 
-#include <base/logging.h>
+#include <bluetooth/log.h>
 
 #include "bta/include/bta_av_api.h"
 #include "include/check.h"
 
+using namespace bluetooth;
+
 // Macro to convert BTA AV audio handle to index and vice versa
 #define BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle) \
   (((bta_av_handle) & (~BTA_AV_CHNL_MSK)) - 1)
@@ -89,3 +91,174 @@ void BtaAvCoPeer::Reset(tBTA_AV_HNDL bta_av_handle) {
   codecs_ = nullptr;
   content_protect_active_ = false;
 }
+
+void BtaAvCoPeerCache::Init(
+    const std::vector<btav_a2dp_codec_config_t>& codec_priorities,
+    std::vector<btav_a2dp_codec_info_t>* supported_codecs) {
+  std::lock_guard<std::recursive_mutex> lock(codec_lock_);
+
+  codec_priorities_ = codec_priorities;
+
+  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
+    BtaAvCoPeer* p_peer = &peers_[i];
+    p_peer->Init(codec_priorities);
+  }
+}
+
+void BtaAvCoPeerCache::Reset() {
+  codec_priorities_.clear();
+
+  // Reset the peers and initialize the handles
+  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
+    BtaAvCoPeer* p_peer = &peers_[i];
+    p_peer->Reset(BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(i));
+  }
+}
+
+BtaAvCoPeer* BtaAvCoPeerCache::FindPeer(const RawAddress& peer_address) {
+  for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
+    BtaAvCoPeer* p_peer = &peers_[i];
+    if (p_peer->addr == peer_address) {
+      return p_peer;
+    }
+  }
+  return nullptr;
+}
+
+BtaAvCoSep* BtaAvCoPeerCache::FindPeerSource(
+    BtaAvCoPeer* p_peer, btav_a2dp_codec_index_t codec_index,
+    const uint8_t content_protect_flag) {
+  if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
+    log::warn("invalid codec index for peer {}",
+              ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
+    return nullptr;
+  }
+
+  // Find the peer Source for the codec
+  for (size_t index = 0; index < p_peer->num_sup_sources; index++) {
+    BtaAvCoSep* p_source = &p_peer->sources[index];
+    btav_a2dp_codec_index_t peer_codec_index =
+        A2DP_SinkCodecIndex(p_source->codec_caps);
+    if (peer_codec_index != codec_index) {
+      continue;
+    }
+    if (!AudioSepHasContentProtection(p_source, content_protect_flag)) {
+      log::verbose(
+          "peer Source for codec {} does not support Content Protection",
+          A2DP_CodecIndexStr(codec_index));
+      continue;
+    }
+    return p_source;
+  }
+  return nullptr;
+}
+
+BtaAvCoSep* BtaAvCoPeerCache::FindPeerSink(BtaAvCoPeer* p_peer,
+                                           btav_a2dp_codec_index_t codec_index,
+                                           const uint8_t content_protect_flag) {
+  if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
+    log::warn("invalid codec index for peer {}",
+              ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
+    return nullptr;
+  }
+
+  // Find the peer Sink for the codec
+  for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
+    BtaAvCoSep* p_sink = &p_peer->sinks[index];
+    btav_a2dp_codec_index_t peer_codec_index =
+        A2DP_SourceCodecIndex(p_sink->codec_caps);
+    if (peer_codec_index != codec_index) {
+      continue;
+    }
+    if (!AudioSepHasContentProtection(p_sink, content_protect_flag)) {
+      log::warn("invalid codec index for peer {}",
+                ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
+      continue;
+    }
+    return p_sink;
+  }
+  return nullptr;
+}
+
+BtaAvCoPeer* BtaAvCoPeerCache::FindPeer(tBTA_AV_HNDL bta_av_handle) {
+  uint8_t index;
+
+  index = BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle);
+
+  log::verbose("bta_av_handle = 0x{:x} index = {}", bta_av_handle, index);
+
+  // Sanity check
+  if (index >= BTA_AV_CO_NUM_ELEMENTS(peers_)) {
+    log::error("peer index {} for BTA AV handle 0x{:x} is out of bounds", index,
+               bta_av_handle);
+    return nullptr;
+  }
+
+  return &peers_[index];
+}
+
+BtaAvCoPeer* BtaAvCoPeerCache::FindPeerAndUpdate(
+    tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) {
+  log::verbose("peer {} bta_av_handle = 0x{:x}",
+               ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle);
+
+  BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
+  if (p_peer == nullptr) {
+    log::error("peer entry for BTA AV handle 0x{:x} peer {} not found",
+               bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address));
+    return nullptr;
+  }
+
+  log::verbose("peer {} bta_av_handle = 0x{:x} previous address {}",
+               ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle,
+               ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr));
+  p_peer->addr = peer_address;
+  return p_peer;
+}
+
+uint16_t BtaAvCoPeerCache::FindPeerUuid(tBTA_AV_HNDL bta_av_handle) {
+  BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
+  if (p_peer == nullptr) {
+    return 0;
+  }
+  return p_peer->uuid_to_connect;
+}
+
+bool ContentProtectIsScmst(const uint8_t* p_protect_info) {
+  log::verbose("");
+
+  if (*p_protect_info >= AVDT_CP_LOSC) {
+    uint16_t cp_id;
+    p_protect_info++;
+    STREAM_TO_UINT16(cp_id, p_protect_info);
+    if (cp_id == AVDT_CP_SCMS_T_ID) {
+      log::verbose("SCMS-T found");
+      return true;
+    }
+  }
+  return false;
+}
+
+bool AudioProtectHasScmst(uint8_t num_protect, const uint8_t* p_protect_info) {
+  log::verbose("");
+  while (num_protect--) {
+    if (ContentProtectIsScmst(p_protect_info)) return true;
+    // Move to the next Content Protect schema
+    p_protect_info += *p_protect_info + 1;
+  }
+  log::verbose("SCMS-T not found");
+  return false;
+}
+
+bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep,
+                                  const uint8_t content_protect_flag) {
+  log::verbose("");
+
+  // Check if content protection is enabled for this stream
+  if (content_protect_flag != AVDT_CP_SCMS_COPY_FREE) {
+    return AudioProtectHasScmst(p_sep->num_protect, p_sep->protect_info);
+  }
+
+  log::verbose("not required");
+  return true;
+}
diff --git a/system/btif/include/bta_av_co.h b/system/btif/include/bta_av_co.h
index e266767fd2f6ab0a5517494e94757776b7fd3bc7..7571bc12e3561da88d5a1f8c5b4fae6545e18206 100644
--- a/system/btif/include/bta_av_co.h
+++ b/system/btif/include/bta_av_co.h
@@ -22,14 +22,17 @@
 
 class BtaAvCo {
  public:
-  BtaAvCo(bool content_protect_enabled)
-      : active_peer_(nullptr),
+  BtaAvCo(bool content_protect_enabled, BtaAvCoPeerCache* bta_av_co_peer_bank)
+      : peer_cache_(bta_av_co_peer_bank),
+        active_peer_(nullptr),
         codec_config_{},
         content_protect_enabled_(content_protect_enabled),
         content_protect_flag_(0) {
     Reset();
   }
 
+  virtual ~BtaAvCo() = default;
+
   /**
    * Initialize the state.
    *
@@ -62,14 +65,6 @@ class BtaAvCo {
    */
   A2dpCodecConfig* GetPeerCurrentCodec(const RawAddress& peer_address);
 
-  /**
-   * Find the peer UUID for a given BTA AV handle.
-   *
-   * @param bta_av_handle the BTA AV handle to use
-   * @return the peer UUID if found, otherwise 0
-   */
-  uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle);
-
   /**
    * Process the AVDTP discovery result: number of Stream End Points (SEP)
    * found during the AVDTP stream discovery process.
@@ -152,7 +147,7 @@ class BtaAvCo {
    * @param seid stream endpoint ID of stream initiating the operation
    * @param peer_address the peer address
    * @param num_protect the peer SEP number of content protection elements
-   * @param p_protect_info the peer SEP conntent protection info
+   * @param p_protect_info the peer SEP content protection info
    * @param t_local_sep the local SEP: AVDT_TSEP_SRC or AVDT_TSEP_SNK
    * @param avdt_handle the AVDTP handle
    */
@@ -351,32 +346,9 @@ class BtaAvCo {
   void DebugDump(int fd);
 
   /**
-   * Find the peer entry for a given peer address.
-   *
-   * @param peer_address the peer address to use
-   * @return the peer entry if found, otherwise nullptr
+   * Access peer data via cache.
    */
-  BtaAvCoPeer* FindPeer(const RawAddress& peer_address);
-
-  /**
-   * Find the peer Sink SEP entry for a given codec index.
-   *
-   * @param p_peer the peer to use
-   * @param codec_index the codec index to use
-   * @return the peer Sink SEP for the codec index if found, otherwise nullptr
-   */
-  BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer,
-                           btav_a2dp_codec_index_t codec_index);
-
-  /**
-   * Find the peer Source SEP entry for a given codec index.
-   *
-   * @param p_peer the peer to use
-   * @param codec_config the codec index to use
-   * @return the peer Source SEP for the codec index if found, otherwise nullptr
-   */
-  BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer,
-                             btav_a2dp_codec_index_t codec_index);
+  BtaAvCoPeerCache* peer_cache_;
 
  private:
   /**
@@ -384,25 +356,6 @@ class BtaAvCo {
    */
   void Reset();
 
-  /**
-   * Find the peer entry for a given BTA AV handle.
-   *
-   * @param bta_av_handle the BTA AV handle to use
-   * @return the peer entry if found, otherwise nullptr
-   */
-  BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle);
-
-  /**
-   * Find the peer entry for a given BTA AV handle and update it with the
-   * peer address.
-   *
-   * @param bta_av_handle the BTA AV handle to use
-   * @param peer_address the peer address
-   * @return the peer entry if found, otherwise nullptr
-   */
-  BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
-                                 const RawAddress& peer_address);
-
   /**
    * Select the Source codec configuration based on peer codec support.
    *
@@ -540,39 +493,9 @@ class BtaAvCo {
       const ::bluetooth::audio::a2dp::provider::a2dp_configuration&
           provider_codec_config);
 
-  /**
-   * Check if a peer SEP has content protection enabled.
-   *
-   * @param p_sep the peer SEP to check
-   * @return true if the peer SEP has content protection enabled,
-   * otherwise false
-   */
-  bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep);
-
-  /**
-   * Check if a content protection service is SCMS-T.
-   *
-   * @param p_orotect_info the content protection info to check
-   * @return true if the Contention Protection in @param p_protect_info
-   * is SCMS-T, otherwise false
-   */
-  static bool ContentProtectIsScmst(const uint8_t* p_protect_info);
-
-  /**
-   * Check if audio protect info contains SCMS-T Content Protection.
-   *
-   * @param num_protect number of protect schemes
-   * @param p_protect_info the protect info to check
-   * @return true if @param p_protect_info contains SCMS-T, otherwise false
-   */
-  static bool AudioProtectHasScmst(uint8_t num_protect,
-                                   const uint8_t* p_protect_info);
-
   bool ContentProtectEnabled() const { return content_protect_enabled_; }
 
-  std::recursive_mutex codec_lock_;  // Protect access to the codec state
-  std::vector<btav_a2dp_codec_config_t> codec_priorities_;  // Configured
-  BtaAvCoPeer peers_[BTA_AV_NUM_STRS];     // Connected peer information
+  // TODO: Remove active peer once no longer needed.
   BtaAvCoPeer* active_peer_;               // The current active peer
   uint8_t codec_config_[AVDT_CODEC_SIZE];  // Current codec configuration
   const bool content_protect_enabled_;     // True if Content Protect is enabled
diff --git a/system/btif/include/bta_av_co_peer.h b/system/btif/include/bta_av_co_peer.h
index 4b269c07edc049392837af1a770c27afdd19610f..7703c3033b4f32f41e08769f7380d195063fc136 100644
--- a/system/btif/include/bta_av_co_peer.h
+++ b/system/btif/include/bta_av_co_peer.h
@@ -50,6 +50,9 @@ class BtaAvCoSep {
 
 class BtaAvCoPeer {
  public:
+  /**
+   * Default constructor to initialize the state of the member variables.
+   */
   BtaAvCoPeer();
 
   /**
@@ -78,7 +81,7 @@ class BtaAvCoPeer {
    *
    * @return the A2DP codecs
    */
-  A2dpCodecs* GetCodecs() { return codecs_; }
+  A2dpCodecs* GetCodecs() const { return codecs_; }
 
   bool ContentProtectActive() const { return content_protect_active_; }
   void SetContentProtectActive(bool cp_active) {
@@ -109,3 +112,115 @@ class BtaAvCoPeer {
   A2dpCodecs* codecs_;           // Locally supported codecs
   bool content_protect_active_;  // True if Content Protect is active
 };
+
+/**
+ * Cache to store all the peer and codec information.
+ * It provides different APIs to retrieve the peer and update the peer data.
+ */
+class BtaAvCoPeerCache {
+ public:
+  BtaAvCoPeerCache() = default;
+  std::recursive_mutex codec_lock_;  // Protect access to the codec state
+  std::vector<btav_a2dp_codec_config_t> codec_priorities_;  // Configured
+  BtaAvCoPeer peers_[BTA_AV_NUM_STRS];  // Connected peer information
+
+  /**
+   * Inits the cache with the appropriate data.
+   * @param codec_priorities codec priorities.
+   * @param supported_codecs supported codecs by the stack.
+   */
+  void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities,
+            std::vector<btav_a2dp_codec_info_t>* supported_codecs);
+
+  /**
+   * Resets the cache and the peer data.
+   */
+  void Reset();
+
+  /**
+   * Find the peer entry for a given peer address.
+   *
+   * @param peer_address the peer address to use
+   * @return the peer entry if found, otherwise nullptr
+   */
+  BtaAvCoPeer* FindPeer(const RawAddress& peer_address);
+
+  /**
+   * Find the peer Source SEP entry for a given codec index.
+   *
+   * @param p_peer the peer to use
+   * @param codec_config the codec index to use
+   * @return the peer Source SEP for the codec index if found, otherwise nullptr
+   */
+  BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer,
+                             btav_a2dp_codec_index_t codec_index,
+                             const uint8_t content_protect_flag);
+
+  /**
+   * Find the peer Sink SEP entry for a given codec index.
+   *
+   * @param p_peer the peer to use
+   * @param codec_index the codec index to use
+   * @return the peer Sink SEP for the codec index if found, otherwise nullptr
+   */
+  BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer,
+                           btav_a2dp_codec_index_t codec_index,
+                           const uint8_t content_protect_flag);
+
+  /**
+   * Find the peer entry for a given BTA AV handle.
+   *
+   * @param bta_av_handle the BTA AV handle to use
+   * @return the peer entry if found, otherwise nullptr
+   */
+  BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle);
+
+  /**
+   * Find the peer entry for a given BTA AV handle and update it with the
+   * peer address.
+   *
+   * @param bta_av_handle the BTA AV handle to use
+   * @param peer_address the peer address
+   * @return the peer entry if found, otherwise nullptr
+   */
+  BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
+                                 const RawAddress& peer_address);
+
+  /**
+   * Find the peer UUID for a given BTA AV handle.
+   *
+   * @param bta_av_handle the BTA AV handle to use
+   * @return the peer UUID if found, otherwise 0
+   */
+  uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle);
+};
+
+/**
+ * Check if a content protection service is SCMS-T.
+ *
+ * @param p_orotect_info the content protection info to check
+ * @return true if the Contention Protection in @param p_protect_info
+ * is SCMS-T, otherwise false
+ */
+bool ContentProtectIsScmst(const uint8_t* p_protect_info);
+
+/**
+ * Check if audio protect info contains SCMS-T Content Protection.
+ *
+ * @param num_protect number of protect schemes
+ * @param p_protect_info the protect info to check
+ * @return true if @param p_protect_info contains SCMS-T, otherwise false
+ */
+bool AudioProtectHasScmst(uint8_t num_protect, const uint8_t* p_protect_info);
+
+/**
+ * Check if a peer SEP has content protection enabled.
+ *
+ * @param p_sep the peer SEP to check
+ * @param content_protect_flag flag to check if content protect is enabled or
+ * not.
+ * @return true if the peer SEP has content protection enabled,
+ * otherwise false
+ */
+bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep,
+                                  const uint8_t content_protect_flag);
diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc
index 4b5fdd513f12207786aeade3a63c8efc05a3568e..2ce600ef145d2c4e9d82f87b26beb7962196c87d 100644
--- a/system/btif/src/btif_av.cc
+++ b/system/btif/src/btif_av.cc
@@ -20,6 +20,7 @@
 
 #include "btif/include/btif_av.h"
 
+#include <android_bluetooth_flags.h>
 #include <android_bluetooth_sysprop.h>
 #include <base/functional/bind.h>
 #include <base/logging.h>