OSDN Git Service

AVRCP Controller manage active device
authorJoseph Pirozzo <pirozzoj@google.com>
Tue, 21 Jan 2020 21:48:30 +0000 (13:48 -0800)
committerJoseph Pirozzo <pirozzoj@google.com>
Wed, 22 Jan 2020 16:47:32 +0000 (08:47 -0800)
Add function to allow the active A2DP sink's peer to be managed via
JNI.  The new logic only decodes A2DP audio packets from the active
device, rather than any device as long as the active device was in
streaming mode.  With this change an A2DP sink may connect up to
kDefaultMaxConnectedAudioDevices A2DP sources and have media browsing
and playback managed correctly.

Bug: 132642754
Test: change constant, connect two devices and play via browsing.
Change-Id: Ia4633aaf2f092a95bd816cf6ca7101210ebcf222

bta/av/bta_av_aact.cc
bta/include/bta_av_api.h
btif/src/btif_av.cc
include/hardware/bt_av.h

index c66d750..29dcea0 100644 (file)
@@ -524,8 +524,8 @@ void bta_av_sink_data_cback(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
     return;
   }
   p_pkt->event = BTA_AV_SINK_MEDIA_DATA_EVT;
-  p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(BTA_AV_SINK_MEDIA_DATA_EVT,
-                                                    (tBTA_AV_MEDIA*)p_pkt);
+  p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
+      p_scb->PeerAddress(), BTA_AV_SINK_MEDIA_DATA_EVT, (tBTA_AV_MEDIA*)p_pkt);
   /* Free the buffer: a copy of the packet has been delivered */
   osi_free(p_pkt);
 }
@@ -1149,8 +1149,8 @@ void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
     tBTA_AV_MEDIA av_sink_codec_info;
     av_sink_codec_info.avk_config.bd_addr = p_scb->PeerAddress();
     av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
-    p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(BTA_AV_SINK_MEDIA_CFG_EVT,
-                                                      &av_sink_codec_info);
+    p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
+        p_scb->PeerAddress(), BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
   }
 
   AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label,
@@ -1770,7 +1770,7 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
       av_sink_codec_info.avk_config.bd_addr = p_scb->PeerAddress();
       av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
       p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
-          BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
+          p_scb->PeerAddress(), BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
     }
 
     if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) {
index 418f012..1450e4e 100644 (file)
@@ -360,7 +360,8 @@ typedef union {
 
 /* AV callback */
 typedef void(tBTA_AV_CBACK)(tBTA_AV_EVT event, tBTA_AV* p_data);
-typedef void(tBTA_AV_SINK_DATA_CBACK)(tBTA_AV_EVT event, tBTA_AV_MEDIA* p_data);
+typedef void(tBTA_AV_SINK_DATA_CBACK)(const RawAddress&, tBTA_AV_EVT event,
+                                      tBTA_AV_MEDIA* p_data);
 
 /* type for stream state machine action functions */
 struct tBTA_AV_SCB;
index 5742a3b..0597e72 100644 (file)
@@ -110,6 +110,7 @@ class BtifAvEvent {
 };
 
 class BtifAvPeer;
+static bt_status_t sink_set_active_device(const RawAddress& peer_address);
 
 // Should not need dedicated Suspend state as actual actions are no
 // different than Open state. Suspend flags are needed however to prevent
@@ -677,7 +678,8 @@ static void btif_av_report_sink_audio_config_state(
     const RawAddress& peer_address, int sample_rate, int channel_count);
 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(tBTA_AV_EVT event,
+static void bta_av_sink_media_callback(const RawAddress& peer_address,
+                                       tBTA_AV_EVT event,
                                        tBTA_AV_MEDIA* p_data);
 
 static BtifAvPeer* btif_av_source_find_peer(const RawAddress& peer_address) {
@@ -1990,6 +1992,8 @@ void BtifAvStateMachine::StateStarted::OnEnter() {
   // We are again in started state, clear any remote suspend flags
   peer_.ClearFlags(BtifAvPeer::kFlagRemoteSuspend);
 
+  btif_a2dp_sink_set_rx_flush(false);
+
   // Report that we have entered the Streaming stage. Usually, this should
   // be followed by focus grant. See update_audio_focus_state()
   btif_report_audio_state(peer_.PeerAddress(), BTAV_AUDIO_STATE_STARTED);
@@ -2591,14 +2595,17 @@ static void bta_av_sink_callback(tBTA_AV_EVT event, tBTA_AV* p_data) {
 }
 
 // TODO: All processing should be done on the JNI thread
-static void bta_av_sink_media_callback(tBTA_AV_EVT event,
+static void bta_av_sink_media_callback(const RawAddress& peer_address,
+                                       tBTA_AV_EVT event,
                                        tBTA_AV_MEDIA* p_data) {
   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
+  BTIF_TRACE_EVENT("%s: address=%s", __func__,
+                   (p_data->avk_config.bd_addr.ToString().c_str()));
 
   switch (event) {
     case BTA_AV_SINK_MEDIA_DATA_EVT: {
-      BtifAvPeer* peer = btif_av_sink_find_peer(btif_av_sink.ActivePeer());
-      if (peer != nullptr) {
+      BtifAvPeer* peer = btif_av_sink_find_peer(peer_address);
+      if (peer != nullptr && peer->IsActivePeer()) {
         int state = peer->StateMachine().StateId();
         if ((state == BtifAvStateMachine::kStateStarted) ||
             (state == BtifAvStateMachine::kStateOpened)) {
@@ -2790,6 +2797,28 @@ static bt_status_t sink_disconnect_src(const RawAddress& peer_address) {
                             peer_address, kBtaHandleUnknown, btif_av_event));
 }
 
+static bt_status_t sink_set_active_device(const RawAddress& peer_address) {
+  BTIF_TRACE_EVENT("%s: Peer %s", __func__, peer_address.ToString().c_str());
+
+  if (!btif_av_sink.Enabled()) {
+    LOG(WARNING) << __func__ << ": BTIF AV Source is not enabled";
+    return BT_STATUS_NOT_READY;
+  }
+
+  std::promise<void> peer_ready_promise;
+  std::future<void> peer_ready_future = peer_ready_promise.get_future();
+  bt_status_t status = do_in_main_thread(
+      FROM_HERE, base::BindOnce(&set_active_peer_int,
+                                AVDT_TSEP_SRC,  // peer_sep
+                                peer_address, std::move(peer_ready_promise)));
+  if (status == BT_STATUS_SUCCESS) {
+    peer_ready_future.wait();
+  } else {
+    LOG(WARNING) << __func__ << ": BTIF AV Sink fails to change peer";
+  }
+  return status;
+}
+
 static bt_status_t src_set_silence_sink(const RawAddress& peer_address,
                                         bool silence) {
   BTIF_TRACE_EVENT("%s: Peer %s", __func__, peer_address.ToString().c_str());
@@ -2878,10 +2907,14 @@ static const btav_source_interface_t bt_av_src_interface = {
 };
 
 static const btav_sink_interface_t bt_av_sink_interface = {
-    sizeof(btav_sink_interface_t), init_sink,    sink_connect_src,
-    sink_disconnect_src,           cleanup_sink, update_audio_focus_state,
+    sizeof(btav_sink_interface_t),
+    init_sink,
+    sink_connect_src,
+    sink_disconnect_src,
+    cleanup_sink,
+    update_audio_focus_state,
     update_audio_track_gain,
-};
+    sink_set_active_device};
 
 RawAddress btif_av_source_active_peer(void) {
   return btif_av_source.ActivePeer();
index 94e320b..41f512b 100644 (file)
@@ -354,6 +354,9 @@ typedef struct {
 
   /** Sets the audio track gain. */
   void (*set_audio_track_gain)(float gain);
+
+  /** sets the connected device as active */
+  bt_status_t (*set_active_device)(const RawAddress& bd_addr);
 } btav_sink_interface_t;
 
 __END_DECLS