OSDN Git Service

Added Start/End Session steps to A2DP session setup
authorPavlin Radoslavov <pavlin@google.com>
Tue, 20 Mar 2018 23:50:57 +0000 (16:50 -0700)
committerPavlin Radoslavov <pavlin@google.com>
Thu, 22 Mar 2018 22:10:00 +0000 (22:10 +0000)
Start/End session is called when setting/changing the Active (remote)
device.

Also:
 * For A2DP Source, btif_a2dp_source_setup_codec() is called only for
   Start session. All other calls to btif_a2dp_source_setup_codec are
   removed.
 * Updated the btif_a2dp_source_setup_codec() implementation to
   call btif_a2dp_source_audio_tx_flush_req() and flush the incoming audio
   data. This removes 2 seconds hold-up delay when switching the active
   device and streaming audio.
 * Removed unnecessary lock inside btif/src/btif_a2dp_sink.cc

Bug: 74952724
Test: Manual - Connect two headsets, switch active device,
      connect/disconnect.
Change-Id: I43702e1ddc108628de93161905465647471f554c
Merged-In: I43702e1ddc108628de93161905465647471f554c
(cherry picked from commit 03adb3f7ba37d637329d3c13aa4a3bb1ec28f143)

btif/include/btif_a2dp_sink.h
btif/include/btif_a2dp_source.h
btif/src/btif_a2dp.cc
btif/src/btif_a2dp_sink.cc
btif/src/btif_a2dp_source.cc
btif/src/btif_av.cc

index 3e64503..8a3c10c 100644 (file)
@@ -49,6 +49,16 @@ bool btif_a2dp_sink_init(void);
 // streaming.
 bool btif_a2dp_sink_startup(void);
 
+// Start the A2DP Sink session.
+// This function should be called by the BTIF state machine after
+// btif_a2dp_sink_startup() to start the streaming session for |peer_address|.
+bool btif_a2dp_sink_start_session(const RawAddress& peer_address);
+
+// End the A2DP Sink session.
+// This function should be called by the BTIF state machine to end the
+// streaming session for |peer_address|.
+bool btif_a2dp_sink_end_session(const RawAddress& peer_address);
+
 // Shutdown the A2DP Sink module.
 // This function should be called by the BTIF state machine before
 // btif_a2dp_sink_cleanup() to shutdown the processing of the audio streaming.
index 193e4b2..1fc7d9a 100644 (file)
@@ -34,6 +34,16 @@ bool btif_a2dp_source_init(void);
 // btif_a2dp_source_init() to prepare to start streaming.
 bool btif_a2dp_source_startup(void);
 
+// Start the A2DP Source session.
+// This function should be called by the BTIF state machine after
+// btif_a2dp_source_startup() to start the streaming session for |peer_address|.
+bool btif_a2dp_source_start_session(const RawAddress& peer_address);
+
+// End the A2DP Source session.
+// This function should be called by the BTIF state machine to end the
+// streaming session for |peer_address|.
+bool btif_a2dp_source_end_session(const RawAddress& peer_address);
+
 // Shutdown the A2DP Source module.
 // This function should be called by the BTIF state machine to stop streaming.
 void btif_a2dp_source_shutdown(void);
index 4cfa300..9524616 100644 (file)
@@ -83,10 +83,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr,
           ack = true;
         }
       } else {
-        /* We were remotely started, make sure codec
-         * is setup before datapath is started.
-         */
-        btif_a2dp_source_setup_codec(peer_addr);
+        // We were started remotely
         if (btif_av_is_a2dp_offload_enabled()) {
           btif_av_stream_start_offload();
         }
index 84205b1..b80cdc7 100644 (file)
@@ -95,6 +95,8 @@ static std::atomic<int> btif_a2dp_sink_state{BTIF_A2DP_SINK_STATE_OFF};
 
 static void btif_a2dp_sink_init_delayed(void* context);
 static void btif_a2dp_sink_startup_delayed(void* context);
+static void btif_a2dp_sink_start_session_delayed(void* context);
+static void btif_a2dp_sink_end_session_delayed(void* context);
 static void btif_a2dp_sink_shutdown_delayed(void* context);
 static void btif_a2dp_sink_cleanup_delayed(void* context);
 static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, void* context);
@@ -170,7 +172,6 @@ static void btif_a2dp_sink_init_delayed(UNUSED_ATTR void* context) {
 
 bool btif_a2dp_sink_startup(void) {
   LOG_INFO(LOG_TAG, "%s", __func__);
-  LockGuard lock(g_mutex);
   thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed,
               NULL);
   return true;
@@ -182,9 +183,36 @@ static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) {
   // Nothing to do
 }
 
-void btif_a2dp_sink_shutdown(void) {
+bool btif_a2dp_sink_start_session(const RawAddress& peer_address) {
+  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
+           peer_address.ToString().c_str());
+  thread_post(btif_a2dp_sink_cb.worker_thread,
+              btif_a2dp_sink_start_session_delayed, NULL);
+  return true;
+}
+
+static void btif_a2dp_sink_start_session_delayed(UNUSED_ATTR void* context) {
+  LOG_INFO(LOG_TAG, "%s", __func__);
+  LockGuard lock(g_mutex);
+  // Nothing to do
+}
+
+bool btif_a2dp_sink_end_session(const RawAddress& peer_address) {
+  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
+           peer_address.ToString().c_str());
+  thread_post(btif_a2dp_sink_cb.worker_thread,
+              btif_a2dp_sink_end_session_delayed, NULL);
+  return true;
+}
+
+static void btif_a2dp_sink_end_session_delayed(UNUSED_ATTR void* context) {
   LOG_INFO(LOG_TAG, "%s", __func__);
   LockGuard lock(g_mutex);
+  // Nothing to do
+}
+
+void btif_a2dp_sink_shutdown(void) {
+  LOG_INFO(LOG_TAG, "%s", __func__);
   thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_shutdown_delayed,
               NULL);
 }
index 2ba70cb..df0a65e 100644 (file)
@@ -301,6 +301,10 @@ static BtifA2dpSource btif_a2dp_source_cb;
 
 static void btif_a2dp_source_init_delayed(void);
 static void btif_a2dp_source_startup_delayed(void);
+static void btif_a2dp_source_start_session_delayed(
+    const RawAddress& peer_address);
+static void btif_a2dp_source_end_session_delayed(
+    const RawAddress& peer_address);
 static void btif_a2dp_source_shutdown_delayed(void);
 static void btif_a2dp_source_cleanup_delayed(void);
 static void btif_a2dp_source_audio_tx_start_event(void);
@@ -421,6 +425,45 @@ static void btif_a2dp_source_startup_delayed(void) {
       system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
 }
 
+bool btif_a2dp_source_start_session(const RawAddress& peer_address) {
+  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
+           peer_address.ToString().c_str());
+  btif_a2dp_source_setup_codec(peer_address);
+  btif_a2dp_source_thread.DoInThread(
+      FROM_HERE,
+      base::Bind(&btif_a2dp_source_start_session_delayed, peer_address));
+  return true;
+}
+
+static void btif_a2dp_source_start_session_delayed(
+    const RawAddress& peer_address) {
+  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
+           peer_address.ToString().c_str());
+  if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) {
+    LOG_ERROR(LOG_TAG, "%s: A2DP Source media task is not running", __func__);
+    return;
+  }
+}
+
+bool btif_a2dp_source_end_session(const RawAddress& peer_address) {
+  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
+           peer_address.ToString().c_str());
+  btif_a2dp_source_thread.DoInThread(
+      FROM_HERE,
+      base::Bind(&btif_a2dp_source_end_session_delayed, peer_address));
+  return true;
+}
+
+static void btif_a2dp_source_end_session_delayed(
+    const RawAddress& peer_address) {
+  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
+           peer_address.ToString().c_str());
+  if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) {
+    LOG_ERROR(LOG_TAG, "%s: A2DP Source media task is not running", __func__);
+    return;
+  }
+}
+
 void btif_a2dp_source_shutdown(void) {
   LOG_INFO(LOG_TAG, "%s", __func__);
 
@@ -491,6 +534,7 @@ void btif_a2dp_source_setup_codec(const RawAddress& peer_address) {
   // we're using that in frame size calculations now.
   CHECK(CHAR_BIT == 8);
 
+  btif_a2dp_source_audio_tx_flush_req();
   btif_a2dp_source_thread.DoInThread(
       FROM_HERE,
       base::Bind(&btif_a2dp_source_setup_codec_delayed, peer_address));
index 724bf3c..6504132 100644 (file)
@@ -405,6 +405,7 @@ class BtifAvSource {
         BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo",
                            __func__);
       }
+      btif_a2dp_source_end_session(active_peer_);
       btif_a2dp_source_shutdown();
       active_peer_ = peer_address;
       return true;
@@ -421,6 +422,11 @@ class BtifAvSource {
                        __func__, peer_address.ToString().c_str());
       return false;
     }
+
+    // Start/restart the session
+    if (!active_peer_.IsEmpty()) {
+      btif_a2dp_source_end_session(active_peer_);
+    }
     bool should_startup = active_peer_.IsEmpty();
     active_peer_ = peer_address;
     if (should_startup) {
@@ -428,6 +434,7 @@ class BtifAvSource {
                        __func__);
       btif_a2dp_source_startup();
     }
+    btif_a2dp_source_start_session(peer_address);
     return true;
   }
 
@@ -522,6 +529,7 @@ class BtifAvSink {
         BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo",
                            __func__);
       }
+      btif_a2dp_sink_end_session(active_peer_);
       btif_a2dp_sink_shutdown();
       active_peer_ = peer_address;
       return true;
@@ -538,6 +546,11 @@ class BtifAvSink {
                        __func__, peer_address.ToString().c_str());
       return false;
     }
+
+    // Start/restart the session
+    if (!active_peer_.IsEmpty()) {
+      btif_a2dp_sink_end_session(active_peer_);
+    }
     bool should_startup = active_peer_.IsEmpty();
     active_peer_ = peer_address;
     if (should_startup) {
@@ -545,6 +558,7 @@ class BtifAvSink {
                        __func__);
       btif_a2dp_sink_startup();
     }
+    btif_a2dp_sink_start_session(peer_address);
     return true;
   }
 
@@ -1703,9 +1717,6 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event,
       break;  // Ignore
 
     case BTIF_AV_START_STREAM_REQ_EVT:
-      if (peer_.IsSink()) {
-        btif_a2dp_source_setup_codec(peer_.PeerAddress());
-      }
       BTA_AvStart(peer_.BtaHandle());
       peer_.SetFlags(BtifAvPeer::kFlagPendingStart);
       break;