1 /******************************************************************************
2 *
3 * Copyright 2016 The Android Open Source Project
4 * Copyright 2009-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 #define LOG_TAG "bt_btif_a2dp_source"
21 #define ATRACE_TAG ATRACE_TAG_AUDIO
22
23 #include <base/run_loop.h>
24 #ifndef OS_GENERIC
25 #include <cutils/trace.h>
26 #endif
27 #include <inttypes.h>
28 #include <limits.h>
29 #include <string.h>
30 #include <algorithm>
31
32 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
33 #include "audio_hal_interface/a2dp_encoding.h"
34 #include "bt_common.h"
35 #include "bta_av_ci.h"
36 #include "btif_a2dp.h"
37 #include "btif_a2dp_audio_interface.h"
38 #include "btif_a2dp_control.h"
39 #include "btif_a2dp_source.h"
40 #include "btif_av.h"
41 #include "btif_av_co.h"
42 #include "btif_util.h"
43 #include "common/message_loop_thread.h"
44 #include "common/metrics.h"
45 #include "common/repeating_timer.h"
46 #include "common/time_util.h"
47 #include "osi/include/fixed_queue.h"
48 #include "osi/include/log.h"
49 #include "osi/include/osi.h"
50 #include "osi/include/wakelock.h"
51 #include "uipc.h"
52
53 using bluetooth::common::A2dpSessionMetrics;
54 using bluetooth::common::BluetoothMetricsLogger;
55 using bluetooth::common::RepeatingTimer;
56
57 extern std::unique_ptr<tUIPC_STATE> a2dp_uipc;
58
59 /**
60 * The typical runlevel of the tx queue size is ~1 buffer
61 * but due to link flow control or thread preemption in lower
62 * layers we might need to temporarily buffer up data.
63 */
64 #define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (MAX_PCM_FRAME_NUM_PER_TICK * 2)
65
66 class SchedulingStats {
67 public:
SchedulingStats()68 SchedulingStats() { Reset(); }
Reset()69 void Reset() {
70 total_updates = 0;
71 last_update_us = 0;
72 overdue_scheduling_count = 0;
73 total_overdue_scheduling_delta_us = 0;
74 max_overdue_scheduling_delta_us = 0;
75 premature_scheduling_count = 0;
76 total_premature_scheduling_delta_us = 0;
77 max_premature_scheduling_delta_us = 0;
78 exact_scheduling_count = 0;
79 total_scheduling_time_us = 0;
80 }
81
82 // Counter for total updates
83 size_t total_updates;
84
85 // Last update timestamp (in us)
86 uint64_t last_update_us;
87
88 // Counter for overdue scheduling
89 size_t overdue_scheduling_count;
90
91 // Accumulated overdue scheduling deviations (in us)
92 uint64_t total_overdue_scheduling_delta_us;
93
94 // Max. overdue scheduling delta time (in us)
95 uint64_t max_overdue_scheduling_delta_us;
96
97 // Counter for premature scheduling
98 size_t premature_scheduling_count;
99
100 // Accumulated premature scheduling deviations (in us)
101 uint64_t total_premature_scheduling_delta_us;
102
103 // Max. premature scheduling delta time (in us)
104 uint64_t max_premature_scheduling_delta_us;
105
106 // Counter for exact scheduling
107 size_t exact_scheduling_count;
108
109 // Accumulated and counted scheduling time (in us)
110 uint64_t total_scheduling_time_us;
111 };
112
113 class BtifMediaStats {
114 public:
BtifMediaStats()115 BtifMediaStats() { Reset(); }
Reset()116 void Reset() {
117 session_start_us = 0;
118 session_end_us = 0;
119 tx_queue_enqueue_stats.Reset();
120 tx_queue_dequeue_stats.Reset();
121 tx_queue_total_frames = 0;
122 tx_queue_max_frames_per_packet = 0;
123 tx_queue_total_queueing_time_us = 0;
124 tx_queue_max_queueing_time_us = 0;
125 tx_queue_total_readbuf_calls = 0;
126 tx_queue_last_readbuf_us = 0;
127 tx_queue_total_flushed_messages = 0;
128 tx_queue_last_flushed_us = 0;
129 tx_queue_total_dropped_messages = 0;
130 tx_queue_max_dropped_messages = 0;
131 tx_queue_dropouts = 0;
132 tx_queue_last_dropouts_us = 0;
133 media_read_total_underflow_bytes = 0;
134 media_read_total_underflow_count = 0;
135 media_read_last_underflow_us = 0;
136 codec_index = -1;
137 }
138
139 uint64_t session_start_us;
140 uint64_t session_end_us;
141
142 SchedulingStats tx_queue_enqueue_stats;
143 SchedulingStats tx_queue_dequeue_stats;
144
145 size_t tx_queue_total_frames;
146 size_t tx_queue_max_frames_per_packet;
147
148 uint64_t tx_queue_total_queueing_time_us;
149 uint64_t tx_queue_max_queueing_time_us;
150
151 size_t tx_queue_total_readbuf_calls;
152 uint64_t tx_queue_last_readbuf_us;
153
154 size_t tx_queue_total_flushed_messages;
155 uint64_t tx_queue_last_flushed_us;
156
157 size_t tx_queue_total_dropped_messages;
158 size_t tx_queue_max_dropped_messages;
159 size_t tx_queue_dropouts;
160 uint64_t tx_queue_last_dropouts_us;
161
162 size_t media_read_total_underflow_bytes;
163 size_t media_read_total_underflow_count;
164 uint64_t media_read_last_underflow_us;
165
166 int codec_index = -1;
167 };
168
169 class BtifA2dpSource {
170 public:
171 enum RunState {
172 kStateOff,
173 kStateStartingUp,
174 kStateRunning,
175 kStateShuttingDown
176 };
177
BtifA2dpSource()178 BtifA2dpSource()
179 : tx_audio_queue(nullptr),
180 tx_flush(false),
181 encoder_interface(nullptr),
182 encoder_interval_ms(0),
183 state_(kStateOff) {}
184
Reset()185 void Reset() {
186 fixed_queue_free(tx_audio_queue, nullptr);
187 tx_audio_queue = nullptr;
188 tx_flush = false;
189 media_alarm.CancelAndWait();
190 wakelock_release();
191 encoder_interface = nullptr;
192 encoder_interval_ms = 0;
193 stats.Reset();
194 accumulated_stats.Reset();
195 state_ = kStateOff;
196 }
197
State() const198 BtifA2dpSource::RunState State() const { return state_; }
StateStr() const199 std::string StateStr() const {
200 switch (state_) {
201 case kStateOff:
202 return "STATE_OFF";
203 case kStateStartingUp:
204 return "STATE_STARTING_UP";
205 case kStateRunning:
206 return "STATE_RUNNING";
207 case kStateShuttingDown:
208 return "STATE_SHUTTING_DOWN";
209 }
210 }
211
SetState(BtifA2dpSource::RunState state)212 void SetState(BtifA2dpSource::RunState state) { state_ = state; }
213
214 fixed_queue_t* tx_audio_queue;
215 bool tx_flush; /* Discards any outgoing data when true */
216 RepeatingTimer media_alarm;
217 const tA2DP_ENCODER_INTERFACE* encoder_interface;
218 uint64_t encoder_interval_ms; /* Local copy of the encoder interval */
219 BtifMediaStats stats;
220 BtifMediaStats accumulated_stats;
221
222 private:
223 BtifA2dpSource::RunState state_;
224 };
225
226 static bluetooth::common::MessageLoopThread btif_a2dp_source_thread(
227 "bt_a2dp_source_worker_thread");
228 static BtifA2dpSource btif_a2dp_source_cb;
229
230 static void btif_a2dp_source_init_delayed(void);
231 static void btif_a2dp_source_startup_delayed(void);
232 static void btif_a2dp_source_start_session_delayed(
233 const RawAddress& peer_address, std::promise<void> start_session_promise);
234 static void btif_a2dp_source_end_session_delayed(
235 const RawAddress& peer_address);
236 static void btif_a2dp_source_shutdown_delayed(void);
237 static void btif_a2dp_source_cleanup_delayed(void);
238 static void btif_a2dp_source_audio_tx_start_event(void);
239 static void btif_a2dp_source_audio_tx_stop_event(void);
240 static void btif_a2dp_source_audio_tx_flush_event(void);
241 // Set up the A2DP Source codec, and prepare the encoder.
242 // The peer address is |peer_addr|.
243 // This function should be called prior to starting A2DP streaming.
244 static void btif_a2dp_source_setup_codec(const RawAddress& peer_addr);
245 static void btif_a2dp_source_setup_codec_delayed(
246 const RawAddress& peer_address);
247 static void btif_a2dp_source_encoder_user_config_update_event(
248 const RawAddress& peer_address,
249 const std::vector<btav_a2dp_codec_config_t>& codec_user_preferences,
250 std::promise<void> peer_ready_promise);
251 static void btif_a2dp_source_audio_feeding_update_event(
252 const btav_a2dp_codec_config_t& codec_audio_config);
253 static bool btif_a2dp_source_audio_tx_flush_req(void);
254 static void btif_a2dp_source_audio_handle_timer(void);
255 static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len);
256 static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n,
257 uint32_t bytes_read);
258 static void log_tstamps_us(const char* comment, uint64_t timestamp_us);
259 static void update_scheduling_stats(SchedulingStats* stats, uint64_t now_us,
260 uint64_t expected_delta);
261 // Update the A2DP Source related metrics.
262 // This function should be called before collecting the metrics.
263 static void btif_a2dp_source_update_metrics(void);
264 static void btm_read_rssi_cb(void* data);
265 static void btm_read_failed_contact_counter_cb(void* data);
266 static void btm_read_automatic_flush_timeout_cb(void* data);
267 static void btm_read_tx_power_cb(void* data);
268
btif_a2dp_source_accumulate_scheduling_stats(SchedulingStats * src,SchedulingStats * dst)269 void btif_a2dp_source_accumulate_scheduling_stats(SchedulingStats* src,
270 SchedulingStats* dst) {
271 dst->total_updates += src->total_updates;
272 dst->last_update_us = src->last_update_us;
273 dst->overdue_scheduling_count += src->overdue_scheduling_count;
274 dst->total_overdue_scheduling_delta_us +=
275 src->total_overdue_scheduling_delta_us;
276 dst->max_overdue_scheduling_delta_us =
277 std::max(dst->max_overdue_scheduling_delta_us,
278 src->max_overdue_scheduling_delta_us);
279 dst->premature_scheduling_count += src->premature_scheduling_count;
280 dst->total_premature_scheduling_delta_us +=
281 src->total_premature_scheduling_delta_us;
282 dst->max_premature_scheduling_delta_us =
283 std::max(dst->max_premature_scheduling_delta_us,
284 src->max_premature_scheduling_delta_us);
285 dst->exact_scheduling_count += src->exact_scheduling_count;
286 dst->total_scheduling_time_us += src->total_scheduling_time_us;
287 }
288
btif_a2dp_source_accumulate_stats(BtifMediaStats * src,BtifMediaStats * dst)289 void btif_a2dp_source_accumulate_stats(BtifMediaStats* src,
290 BtifMediaStats* dst) {
291 dst->tx_queue_total_frames += src->tx_queue_total_frames;
292 dst->tx_queue_max_frames_per_packet = std::max(
293 dst->tx_queue_max_frames_per_packet, src->tx_queue_max_frames_per_packet);
294 dst->tx_queue_total_queueing_time_us += src->tx_queue_total_queueing_time_us;
295 dst->tx_queue_max_queueing_time_us = std::max(
296 dst->tx_queue_max_queueing_time_us, src->tx_queue_max_queueing_time_us);
297 dst->tx_queue_total_readbuf_calls += src->tx_queue_total_readbuf_calls;
298 dst->tx_queue_last_readbuf_us = src->tx_queue_last_readbuf_us;
299 dst->tx_queue_total_flushed_messages += src->tx_queue_total_flushed_messages;
300 dst->tx_queue_last_flushed_us = src->tx_queue_last_flushed_us;
301 dst->tx_queue_total_dropped_messages += src->tx_queue_total_dropped_messages;
302 dst->tx_queue_max_dropped_messages = std::max(
303 dst->tx_queue_max_dropped_messages, src->tx_queue_max_dropped_messages);
304 dst->tx_queue_dropouts += src->tx_queue_dropouts;
305 dst->tx_queue_last_dropouts_us = src->tx_queue_last_dropouts_us;
306 dst->media_read_total_underflow_bytes +=
307 src->media_read_total_underflow_bytes;
308 dst->media_read_total_underflow_count +=
309 src->media_read_total_underflow_count;
310 dst->media_read_last_underflow_us = src->media_read_last_underflow_us;
311 if (dst->codec_index < 0) dst->codec_index = src->codec_index;
312 btif_a2dp_source_accumulate_scheduling_stats(&src->tx_queue_enqueue_stats,
313 &dst->tx_queue_enqueue_stats);
314 btif_a2dp_source_accumulate_scheduling_stats(&src->tx_queue_dequeue_stats,
315 &dst->tx_queue_dequeue_stats);
316 src->Reset();
317 }
318
btif_a2dp_source_init(void)319 bool btif_a2dp_source_init(void) {
320 LOG_INFO("%s", __func__);
321
322 // Start A2DP Source media task
323 btif_a2dp_source_thread.StartUp();
324 btif_a2dp_source_thread.DoInThread(
325 FROM_HERE, base::Bind(&btif_a2dp_source_init_delayed));
326 return true;
327 }
328
btif_a2dp_source_init_delayed(void)329 static void btif_a2dp_source_init_delayed(void) {
330 LOG_INFO("%s", __func__);
331 // Nothing to do
332 }
333
btif_a2dp_source_startup(void)334 bool btif_a2dp_source_startup(void) {
335 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
336
337 if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateOff) {
338 LOG_ERROR("%s: A2DP Source media task already running", __func__);
339 return false;
340 }
341
342 btif_a2dp_source_cb.Reset();
343 btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateStartingUp);
344 btif_a2dp_source_cb.tx_audio_queue = fixed_queue_new(SIZE_MAX);
345
346 // Schedule the rest of the operations
347 btif_a2dp_source_thread.DoInThread(
348 FROM_HERE, base::Bind(&btif_a2dp_source_startup_delayed));
349
350 return true;
351 }
352
btif_a2dp_source_startup_delayed()353 static void btif_a2dp_source_startup_delayed() {
354 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
355 if (!btif_a2dp_source_thread.EnableRealTimeScheduling()) {
356 LOG(FATAL) << __func__ << ": unable to enable real time scheduling";
357 }
358 if (!bluetooth::audio::a2dp::init(&btif_a2dp_source_thread)) {
359 if (btif_av_is_a2dp_offload_enabled()) {
360 // TODO: BluetoothA2dp@1.0 is deprecated
361 LOG(WARNING) << __func__ << ": Using BluetoothA2dp HAL";
362 } else {
363 LOG(WARNING) << __func__ << ": Using legacy HAL";
364 btif_a2dp_control_init();
365 }
366 }
367 btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateRunning);
368 }
369
btif_a2dp_source_start_session(const RawAddress & peer_address,std::promise<void> peer_ready_promise)370 bool btif_a2dp_source_start_session(const RawAddress& peer_address,
371 std::promise<void> peer_ready_promise) {
372 LOG(INFO) << __func__ << ": peer_address=" << peer_address
373 << " state=" << btif_a2dp_source_cb.StateStr();
374 btif_a2dp_source_setup_codec(peer_address);
375 if (btif_a2dp_source_thread.DoInThread(
376 FROM_HERE,
377 base::BindOnce(&btif_a2dp_source_start_session_delayed, peer_address,
378 std::move(peer_ready_promise)))) {
379 return true;
380 } else {
381 // cannot set promise but triggers crash
382 LOG(FATAL) << __func__ << ": peer_address=" << peer_address
383 << " state=" << btif_a2dp_source_cb.StateStr()
384 << " fails to context switch";
385 return false;
386 }
387 }
388
btif_a2dp_source_start_session_delayed(const RawAddress & peer_address,std::promise<void> peer_ready_promise)389 static void btif_a2dp_source_start_session_delayed(
390 const RawAddress& peer_address, std::promise<void> peer_ready_promise) {
391 LOG(INFO) << __func__ << ": peer_address=" << peer_address
392 << " state=" << btif_a2dp_source_cb.StateStr();
393 if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) {
394 LOG(ERROR) << __func__ << ": A2DP Source media task is not running";
395 peer_ready_promise.set_value();
396 return;
397 }
398 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
399 bluetooth::audio::a2dp::start_session();
400 bluetooth::audio::a2dp::set_remote_delay(btif_av_get_audio_delay());
401 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
402 bluetooth::common::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
403 } else if (btif_av_is_a2dp_offload_enabled()) {
404 // TODO: BluetoothA2dp@1.0 is deprecated
405 btif_a2dp_audio_interface_start_session();
406 } else {
407 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
408 bluetooth::common::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
409 }
410 peer_ready_promise.set_value();
411 }
412
btif_a2dp_source_restart_session(const RawAddress & old_peer_address,const RawAddress & new_peer_address,std::promise<void> peer_ready_promise)413 bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
414 const RawAddress& new_peer_address,
415 std::promise<void> peer_ready_promise) {
416 bool is_streaming = btif_a2dp_source_cb.media_alarm.IsScheduled();
417 LOG(INFO) << __func__ << ": old_peer_address=" << old_peer_address
418 << " new_peer_address=" << new_peer_address
419 << " is_streaming=" << logbool(is_streaming)
420 << " state=" << btif_a2dp_source_cb.StateStr();
421
422 CHECK(!new_peer_address.IsEmpty());
423
424 // Must stop first the audio streaming
425 if (is_streaming) {
426 btif_a2dp_source_stop_audio_req();
427 }
428
429 // If the old active peer was valid, end the old session.
430 // Otherwise, time to startup the A2DP Source processing.
431 if (!old_peer_address.IsEmpty()) {
432 btif_a2dp_source_end_session(old_peer_address);
433 } else {
434 btif_a2dp_source_startup();
435 }
436
437 // Start the session.
438 btif_a2dp_source_start_session(new_peer_address,
439 std::move(peer_ready_promise));
440 // If audio was streaming before, DON'T start audio streaming, but leave the
441 // control to the audio HAL.
442 return true;
443 }
444
btif_a2dp_source_end_session(const RawAddress & peer_address)445 bool btif_a2dp_source_end_session(const RawAddress& peer_address) {
446 LOG_INFO("%s: peer_address=%s state=%s", __func__,
447 peer_address.ToString().c_str(),
448 btif_a2dp_source_cb.StateStr().c_str());
449 btif_a2dp_source_thread.DoInThread(
450 FROM_HERE,
451 base::Bind(&btif_a2dp_source_end_session_delayed, peer_address));
452 return true;
453 }
454
btif_a2dp_source_end_session_delayed(const RawAddress & peer_address)455 static void btif_a2dp_source_end_session_delayed(
456 const RawAddress& peer_address) {
457 LOG_INFO("%s: peer_address=%s state=%s", __func__,
458 peer_address.ToString().c_str(),
459 btif_a2dp_source_cb.StateStr().c_str());
460 if ((btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning) ||
461 (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateShuttingDown)) {
462 btif_av_stream_stop(peer_address);
463 } else {
464 LOG_ERROR("%s: A2DP Source media task is not running", __func__);
465 }
466 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
467 bluetooth::audio::a2dp::end_session();
468 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
469 bluetooth::common::DISCONNECT_REASON_UNKNOWN, 0);
470 } else if (btif_av_is_a2dp_offload_enabled()) {
471 // TODO: BluetoothA2dp@1.0 is deprecated
472 btif_a2dp_audio_interface_end_session();
473 } else {
474 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
475 bluetooth::common::DISCONNECT_REASON_UNKNOWN, 0);
476 }
477 }
478
btif_a2dp_source_shutdown(void)479 void btif_a2dp_source_shutdown(void) {
480 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
481
482 if ((btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) ||
483 (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateShuttingDown)) {
484 return;
485 }
486
487 /* Make sure no channels are restarted while shutting down */
488 btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateShuttingDown);
489
490 btif_a2dp_source_thread.DoInThread(
491 FROM_HERE, base::Bind(&btif_a2dp_source_shutdown_delayed));
492 }
493
btif_a2dp_source_shutdown_delayed(void)494 static void btif_a2dp_source_shutdown_delayed(void) {
495 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
496
497 // Stop the timer
498 btif_a2dp_source_cb.media_alarm.CancelAndWait();
499 wakelock_release();
500
501 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
502 bluetooth::audio::a2dp::cleanup();
503 } else if (btif_av_is_a2dp_offload_enabled()) {
504 // TODO: BluetoothA2dp@1.0 is deprecated
505 btif_a2dp_audio_interface_end_session();
506 } else {
507 btif_a2dp_control_cleanup();
508 }
509 fixed_queue_free(btif_a2dp_source_cb.tx_audio_queue, nullptr);
510 btif_a2dp_source_cb.tx_audio_queue = nullptr;
511
512 btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateOff);
513 }
514
btif_a2dp_source_cleanup(void)515 void btif_a2dp_source_cleanup(void) {
516 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
517
518 // Make sure the source is shutdown
519 btif_a2dp_source_shutdown();
520
521 btif_a2dp_source_thread.DoInThread(
522 FROM_HERE, base::Bind(&btif_a2dp_source_cleanup_delayed));
523
524 // Exit the thread
525 btif_a2dp_source_thread.ShutDown();
526 }
527
btif_a2dp_source_cleanup_delayed(void)528 static void btif_a2dp_source_cleanup_delayed(void) {
529 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
530 // Nothing to do
531 }
532
btif_a2dp_source_media_task_is_running(void)533 bool btif_a2dp_source_media_task_is_running(void) {
534 return (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning);
535 }
536
btif_a2dp_source_media_task_is_shutting_down(void)537 bool btif_a2dp_source_media_task_is_shutting_down(void) {
538 return (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateShuttingDown);
539 }
540
btif_a2dp_source_is_streaming(void)541 bool btif_a2dp_source_is_streaming(void) {
542 return btif_a2dp_source_cb.media_alarm.IsScheduled();
543 }
544
btif_a2dp_source_setup_codec(const RawAddress & peer_address)545 static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) {
546 LOG_INFO("%s: peer_address=%s state=%s", __func__,
547 peer_address.ToString().c_str(),
548 btif_a2dp_source_cb.StateStr().c_str());
549
550 // Check to make sure the platform has 8 bits/byte since
551 // we're using that in frame size calculations now.
552 CHECK(CHAR_BIT == 8);
553
554 btif_a2dp_source_audio_tx_flush_req();
555 btif_a2dp_source_thread.DoInThread(
556 FROM_HERE,
557 base::Bind(&btif_a2dp_source_setup_codec_delayed, peer_address));
558 }
559
btif_a2dp_source_setup_codec_delayed(const RawAddress & peer_address)560 static void btif_a2dp_source_setup_codec_delayed(
561 const RawAddress& peer_address) {
562 LOG_INFO("%s: peer_address=%s state=%s", __func__,
563 peer_address.ToString().c_str(),
564 btif_a2dp_source_cb.StateStr().c_str());
565
566 tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
567 bta_av_co_get_peer_params(peer_address, &peer_params);
568
569 if (!bta_av_co_set_active_peer(peer_address)) {
570 LOG_ERROR("%s: Cannot stream audio: cannot set active peer to %s", __func__,
571 peer_address.ToString().c_str());
572 return;
573 }
574 btif_a2dp_source_cb.encoder_interface = bta_av_co_get_encoder_interface();
575 if (btif_a2dp_source_cb.encoder_interface == nullptr) {
576 LOG_ERROR("%s: Cannot stream audio: no source encoder interface", __func__);
577 return;
578 }
579
580 A2dpCodecConfig* a2dp_codec_config = bta_av_get_a2dp_current_codec();
581 if (a2dp_codec_config == nullptr) {
582 LOG_ERROR("%s: Cannot stream audio: current codec is not set", __func__);
583 return;
584 }
585
586 btif_a2dp_source_cb.encoder_interface->encoder_init(
587 &peer_params, a2dp_codec_config, btif_a2dp_source_read_callback,
588 btif_a2dp_source_enqueue_callback);
589
590 // Save a local copy of the encoder_interval_ms
591 btif_a2dp_source_cb.encoder_interval_ms =
592 btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms();
593
594 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
595 bluetooth::audio::a2dp::setup_codec();
596 }
597 }
598
btif_a2dp_source_start_audio_req(void)599 void btif_a2dp_source_start_audio_req(void) {
600 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
601
602 btif_a2dp_source_thread.DoInThread(
603 FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_start_event));
604 }
605
btif_a2dp_source_stop_audio_req(void)606 void btif_a2dp_source_stop_audio_req(void) {
607 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
608
609 btif_a2dp_source_thread.DoInThread(
610 FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_stop_event));
611 }
612
btif_a2dp_source_encoder_user_config_update_req(const RawAddress & peer_address,const std::vector<btav_a2dp_codec_config_t> & codec_user_preferences,std::promise<void> peer_ready_promise)613 void btif_a2dp_source_encoder_user_config_update_req(
614 const RawAddress& peer_address,
615 const std::vector<btav_a2dp_codec_config_t>& codec_user_preferences,
616 std::promise<void> peer_ready_promise) {
617 LOG(INFO) << __func__ << ": peer_address=" << peer_address
618 << " state=" << btif_a2dp_source_cb.StateStr() << " "
619 << codec_user_preferences.size() << " codec_preference(s)";
620 if (!btif_a2dp_source_thread.DoInThread(
621 FROM_HERE,
622 base::BindOnce(&btif_a2dp_source_encoder_user_config_update_event,
623 peer_address, codec_user_preferences,
624 std::move(peer_ready_promise)))) {
625 // cannot set promise but triggers crash
626 LOG(FATAL) << __func__ << ": peer_address=" << peer_address
627 << " state=" << btif_a2dp_source_cb.StateStr()
628 << " fails to context switch";
629 }
630 }
631
btif_a2dp_source_encoder_user_config_update_event(const RawAddress & peer_address,const std::vector<btav_a2dp_codec_config_t> & codec_user_preferences,std::promise<void> peer_ready_promise)632 static void btif_a2dp_source_encoder_user_config_update_event(
633 const RawAddress& peer_address,
634 const std::vector<btav_a2dp_codec_config_t>& codec_user_preferences,
635 std::promise<void> peer_ready_promise) {
636 bool restart_output = false;
637 bool success = false;
638 for (auto codec_user_config : codec_user_preferences) {
639 success = bta_av_co_set_codec_user_config(peer_address, codec_user_config,
640 &restart_output);
641 if (success) {
642 LOG(INFO) << __func__ << ": peer_address=" << peer_address
643 << " state=" << btif_a2dp_source_cb.StateStr()
644 << " codec_preference={" << codec_user_config.ToString()
645 << "} restart_output=" << (restart_output ? "true" : "false");
646 break;
647 }
648 }
649 if (success && restart_output) {
650 // Codec reconfiguration is in progress, and it is safe to unlock since
651 // remaining tasks like starting audio session and reporting new codec
652 // will be handled by BTA_AV_RECONFIG_EVT later.
653 peer_ready_promise.set_value();
654 return;
655 }
656 if (!success) {
657 LOG(ERROR) << __func__ << ": cannot update codec user configuration(s)";
658 }
659 if (!peer_address.IsEmpty() && peer_address == btif_av_source_active_peer()) {
660 // No more actions needed with remote, and if succeed, user had changed the
661 // config like the bits per sample only. Let's resume the session now.
662 btif_a2dp_source_start_session(peer_address, std::move(peer_ready_promise));
663 } else {
664 // Unlock for non-active peer
665 peer_ready_promise.set_value();
666 }
667 }
668
btif_a2dp_source_feeding_update_req(const btav_a2dp_codec_config_t & codec_audio_config)669 void btif_a2dp_source_feeding_update_req(
670 const btav_a2dp_codec_config_t& codec_audio_config) {
671 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
672 btif_a2dp_source_thread.DoInThread(
673 FROM_HERE, base::Bind(&btif_a2dp_source_audio_feeding_update_event,
674 codec_audio_config));
675 }
676
btif_a2dp_source_audio_feeding_update_event(const btav_a2dp_codec_config_t & codec_audio_config)677 static void btif_a2dp_source_audio_feeding_update_event(
678 const btav_a2dp_codec_config_t& codec_audio_config) {
679 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
680 if (!bta_av_co_set_codec_audio_config(codec_audio_config)) {
681 LOG_ERROR("%s: cannot update codec audio feeding parameters", __func__);
682 }
683 }
684
btif_a2dp_source_on_idle(void)685 void btif_a2dp_source_on_idle(void) {
686 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
687 if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return;
688
689 /* Make sure media task is stopped */
690 btif_a2dp_source_stop_audio_req();
691 }
692
btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND * p_av_suspend)693 void btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
694 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
695
696 if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return;
697
698 // allow using this API for other (acknowledgement and stopping media task)
699 // than suspend
700 if (p_av_suspend != nullptr && p_av_suspend->status != BTA_AV_SUCCESS) {
701 LOG_ERROR("%s: A2DP stop failed: status=%d, initiator=%s", __func__,
702 p_av_suspend->status,
703 (p_av_suspend->initiator ? "true" : "false"));
704 if (p_av_suspend->initiator) {
705 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
706 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_FAILURE);
707 } else {
708 btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
709 }
710 }
711 } else if (btif_av_is_a2dp_offload_running()) {
712 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_SUCCESS);
713 return;
714 }
715
716 // ensure tx frames are immediately suspended
717 btif_a2dp_source_cb.tx_flush = true;
718 // ensure tx frames are immediately flushed
719 btif_a2dp_source_audio_tx_flush_req();
720
721 // request to stop media task
722 btif_a2dp_source_stop_audio_req();
723
724 // once software stream is fully stopped we will ack back
725 }
726
btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND * p_av_suspend)727 void btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
728 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
729
730 if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return;
731
732 CHECK(p_av_suspend != nullptr) << "Suspend result could not be nullptr";
733
734 // check for status failures
735 if (p_av_suspend->status != BTA_AV_SUCCESS) {
736 LOG_WARN("%s: A2DP suspend failed: status=%d, initiator=%s", __func__,
737 p_av_suspend->status,
738 (p_av_suspend->initiator ? "true" : "false"));
739 if (p_av_suspend->initiator) {
740 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
741 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_FAILURE);
742 } else {
743 btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
744 }
745 }
746 } else if (btif_av_is_a2dp_offload_running()) {
747 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_SUCCESS);
748 return;
749 }
750
751 // ensure tx frames are immediately suspended
752 btif_a2dp_source_cb.tx_flush = true;
753
754 // stop timer tick
755 btif_a2dp_source_stop_audio_req();
756
757 // once software stream is fully stopped we will ack back
758 }
759
760 /* when true media task discards any tx frames */
btif_a2dp_source_set_tx_flush(bool enable)761 void btif_a2dp_source_set_tx_flush(bool enable) {
762 LOG_INFO("%s: enable=%s state=%s", __func__, (enable) ? "true" : "false",
763 btif_a2dp_source_cb.StateStr().c_str());
764 btif_a2dp_source_cb.tx_flush = enable;
765 }
766
btif_a2dp_source_audio_tx_start_event(void)767 static void btif_a2dp_source_audio_tx_start_event(void) {
768 LOG_INFO(
769 "%s: media_alarm is %s, streaming %s state=%s", __func__,
770 btif_a2dp_source_cb.media_alarm.IsScheduled() ? "running" : "stopped",
771 btif_a2dp_source_is_streaming() ? "true" : "false",
772 btif_a2dp_source_cb.StateStr().c_str());
773
774 if (btif_av_is_a2dp_offload_running()) return;
775
776 /* Reset the media feeding state */
777 CHECK(btif_a2dp_source_cb.encoder_interface != nullptr);
778 btif_a2dp_source_cb.encoder_interface->feeding_reset();
779
780 APPL_TRACE_EVENT(
781 "%s: starting timer %" PRIu64 " ms", __func__,
782 btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms());
783
784 /* audio engine starting, reset tx suspended flag */
785 btif_a2dp_source_cb.tx_flush = false;
786
787 wakelock_acquire();
788 btif_a2dp_source_cb.media_alarm.SchedulePeriodic(
789 btif_a2dp_source_thread.GetWeakPtr(), FROM_HERE,
790 base::Bind(&btif_a2dp_source_audio_handle_timer),
791 base::TimeDelta::FromMilliseconds(
792 btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms()));
793
794 btif_a2dp_source_cb.stats.Reset();
795 // Assign session_start_us to 1 when
796 // bluetooth::common::time_get_os_boottime_us() is 0 to indicate
797 // btif_a2dp_source_start_audio_req() has been called
798 btif_a2dp_source_cb.stats.session_start_us =
799 bluetooth::common::time_get_os_boottime_us();
800 if (btif_a2dp_source_cb.stats.session_start_us == 0) {
801 btif_a2dp_source_cb.stats.session_start_us = 1;
802 }
803 btif_a2dp_source_cb.stats.session_end_us = 0;
804 A2dpCodecConfig* codec_config = bta_av_get_a2dp_current_codec();
805 if (codec_config != nullptr) {
806 btif_a2dp_source_cb.stats.codec_index = codec_config->codecIndex();
807 }
808 }
809
btif_a2dp_source_audio_tx_stop_event(void)810 static void btif_a2dp_source_audio_tx_stop_event(void) {
811 LOG_INFO(
812 "%s: media_alarm is %s, streaming %s state=%s", __func__,
813 btif_a2dp_source_cb.media_alarm.IsScheduled() ? "running" : "stopped",
814 btif_a2dp_source_is_streaming() ? "true" : "false",
815 btif_a2dp_source_cb.StateStr().c_str());
816
817 if (btif_av_is_a2dp_offload_running()) return;
818
819 btif_a2dp_source_cb.stats.session_end_us =
820 bluetooth::common::time_get_os_boottime_us();
821 btif_a2dp_source_update_metrics();
822 btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
823 &btif_a2dp_source_cb.accumulated_stats);
824
825 uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
826 uint16_t event;
827
828 // Keep track of audio data still left in the pipe
829 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
830 btif_a2dp_control_log_bytes_read(
831 bluetooth::audio::a2dp::read(p_buf, sizeof(p_buf)));
832 } else if (a2dp_uipc != nullptr) {
833 btif_a2dp_control_log_bytes_read(UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO,
834 &event, p_buf, sizeof(p_buf)));
835 }
836
837 /* Stop the timer first */
838 btif_a2dp_source_cb.media_alarm.CancelAndWait();
839 wakelock_release();
840
841 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
842 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_SUCCESS);
843 } else if (a2dp_uipc != nullptr) {
844 UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO);
845
846 /*
847 * Try to send acknowledgement once the media stream is
848 * stopped. This will make sure that the A2DP HAL layer is
849 * un-blocked on wait for acknowledgment for the sent command.
850 * This resolves a corner cases AVDTP SUSPEND collision
851 * when the DUT and the remote device issue SUSPEND simultaneously
852 * and due to the processing of the SUSPEND request from the remote,
853 * the media path is torn down. If the A2DP HAL happens to wait
854 * for ACK for the initiated SUSPEND, it would never receive it casuing
855 * a block/wait. Due to this acknowledgement, the A2DP HAL is guranteed
856 * to get the ACK for any pending command in such cases.
857 */
858
859 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
860 }
861
862 /* audio engine stopped, reset tx suspended flag */
863 btif_a2dp_source_cb.tx_flush = false;
864
865 /* Reset the media feeding state */
866 if (btif_a2dp_source_cb.encoder_interface != nullptr)
867 btif_a2dp_source_cb.encoder_interface->feeding_reset();
868 }
869
btif_a2dp_source_audio_handle_timer(void)870 static void btif_a2dp_source_audio_handle_timer(void) {
871 if (btif_av_is_a2dp_offload_running()) return;
872
873 uint64_t timestamp_us = bluetooth::common::time_get_os_boottime_us();
874 log_tstamps_us("A2DP Source tx timer", timestamp_us);
875
876 if (!btif_a2dp_source_cb.media_alarm.IsScheduled()) {
877 LOG_ERROR("%s: ERROR Media task Scheduled after Suspend", __func__);
878 return;
879 }
880 CHECK(btif_a2dp_source_cb.encoder_interface != nullptr);
881 size_t transmit_queue_length =
882 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
883 #ifndef OS_GENERIC
884 ATRACE_INT("btif TX queue", transmit_queue_length);
885 #endif
886 if (btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length !=
887 nullptr) {
888 btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length(
889 transmit_queue_length);
890 }
891 btif_a2dp_source_cb.encoder_interface->send_frames(timestamp_us);
892 bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
893 update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_enqueue_stats,
894 timestamp_us,
895 btif_a2dp_source_cb.encoder_interval_ms * 1000);
896 }
897
btif_a2dp_source_read_callback(uint8_t * p_buf,uint32_t len)898 static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) {
899 uint16_t event;
900 uint32_t bytes_read = 0;
901
902 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
903 bytes_read = bluetooth::audio::a2dp::read(p_buf, len);
904 } else if (a2dp_uipc != nullptr) {
905 bytes_read = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, &event, p_buf, len);
906 }
907
908 if (bytes_read < len) {
909 LOG_WARN("%s: UNDERFLOW: ONLY READ %d BYTES OUT OF %d", __func__,
910 bytes_read, len);
911 btif_a2dp_source_cb.stats.media_read_total_underflow_bytes +=
912 (len - bytes_read);
913 btif_a2dp_source_cb.stats.media_read_total_underflow_count++;
914 btif_a2dp_source_cb.stats.media_read_last_underflow_us =
915 bluetooth::common::time_get_os_boottime_us();
916 bluetooth::common::LogA2dpAudioUnderrunEvent(
917 btif_av_source_active_peer(), btif_a2dp_source_cb.encoder_interval_ms,
918 len - bytes_read);
919 }
920
921 return bytes_read;
922 }
923
btif_a2dp_source_enqueue_callback(BT_HDR * p_buf,size_t frames_n,uint32_t bytes_read)924 static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n,
925 uint32_t bytes_read) {
926 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
927 btif_a2dp_control_log_bytes_read(bytes_read);
928
929 /* Check if timer was stopped (media task stopped) */
930 if (!btif_a2dp_source_cb.media_alarm.IsScheduled()) {
931 osi_free(p_buf);
932 return false;
933 }
934
935 /* Check if the transmission queue has been flushed */
936 if (btif_a2dp_source_cb.tx_flush) {
937 LOG_VERBOSE("%s: tx suspended, discarded frame", __func__);
938
939 btif_a2dp_source_cb.stats.tx_queue_total_flushed_messages +=
940 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
941 btif_a2dp_source_cb.stats.tx_queue_last_flushed_us = now_us;
942 fixed_queue_flush(btif_a2dp_source_cb.tx_audio_queue, osi_free);
943
944 osi_free(p_buf);
945 return false;
946 }
947
948 // Check for TX queue overflow
949 // TODO: Using frames_n here is probably wrong: should be "+ 1" instead.
950 if (fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue) + frames_n >
951 MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) {
952 LOG_WARN("%s: TX queue buffer size now=%u adding=%u max=%d", __func__,
953 (uint32_t)fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue),
954 (uint32_t)frames_n, MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ);
955 // Keep track of drop-outs
956 btif_a2dp_source_cb.stats.tx_queue_dropouts++;
957 btif_a2dp_source_cb.stats.tx_queue_last_dropouts_us = now_us;
958
959 // Flush all queued buffers
960 size_t drop_n = fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
961 btif_a2dp_source_cb.stats.tx_queue_max_dropped_messages = std::max(
962 drop_n, btif_a2dp_source_cb.stats.tx_queue_max_dropped_messages);
963 int num_dropped_encoded_bytes = 0;
964 int num_dropped_encoded_frames = 0;
965 while (fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue)) {
966 btif_a2dp_source_cb.stats.tx_queue_total_dropped_messages++;
967 void* p_data =
968 fixed_queue_try_dequeue(btif_a2dp_source_cb.tx_audio_queue);
969 if (p_data != nullptr) {
970 auto p_dropped_buf = static_cast<BT_HDR*>(p_data);
971 num_dropped_encoded_bytes += p_dropped_buf->len;
972 num_dropped_encoded_frames += p_dropped_buf->layer_specific;
973 osi_free(p_data);
974 }
975 }
976 bluetooth::common::LogA2dpAudioOverrunEvent(
977 btif_av_source_active_peer(), drop_n,
978 btif_a2dp_source_cb.encoder_interval_ms, num_dropped_encoded_frames,
979 num_dropped_encoded_bytes);
980
981 // Request additional debug info if we had to flush buffers
982 RawAddress peer_bda = btif_av_source_active_peer();
983 tBTM_STATUS status = BTM_ReadRSSI(peer_bda, btm_read_rssi_cb);
984 if (status != BTM_CMD_STARTED) {
985 LOG_WARN("%s: Cannot read RSSI: status %d", __func__, status);
986 }
987 status = BTM_ReadFailedContactCounter(peer_bda,
988 btm_read_failed_contact_counter_cb);
989 if (status != BTM_CMD_STARTED) {
990 LOG_WARN("%s: Cannot read Failed Contact Counter: status %d", __func__,
991 status);
992 }
993 status = BTM_ReadAutomaticFlushTimeout(peer_bda,
994 btm_read_automatic_flush_timeout_cb);
995 if (status != BTM_CMD_STARTED) {
996 LOG_WARN("%s: Cannot read Automatic Flush Timeout: status %d", __func__,
997 status);
998 }
999 status =
1000 BTM_ReadTxPower(peer_bda, BT_TRANSPORT_BR_EDR, btm_read_tx_power_cb);
1001 if (status != BTM_CMD_STARTED) {
1002 LOG_WARN("%s: Cannot read Tx Power: status %d", __func__, status);
1003 }
1004 }
1005
1006 /* Update the statistics */
1007 btif_a2dp_source_cb.stats.tx_queue_total_frames += frames_n;
1008 btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet = std::max(
1009 frames_n, btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet);
1010 CHECK(btif_a2dp_source_cb.encoder_interface != nullptr);
1011
1012 fixed_queue_enqueue(btif_a2dp_source_cb.tx_audio_queue, p_buf);
1013
1014 return true;
1015 }
1016
btif_a2dp_source_audio_tx_flush_event(void)1017 static void btif_a2dp_source_audio_tx_flush_event(void) {
1018 /* Flush all enqueued audio buffers (encoded) */
1019 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
1020 if (btif_av_is_a2dp_offload_running()) return;
1021
1022 if (btif_a2dp_source_cb.encoder_interface != nullptr)
1023 btif_a2dp_source_cb.encoder_interface->feeding_flush();
1024
1025 btif_a2dp_source_cb.stats.tx_queue_total_flushed_messages +=
1026 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
1027 btif_a2dp_source_cb.stats.tx_queue_last_flushed_us =
1028 bluetooth::common::time_get_os_boottime_us();
1029 fixed_queue_flush(btif_a2dp_source_cb.tx_audio_queue, osi_free);
1030
1031 if (!bluetooth::audio::a2dp::is_hal_2_0_enabled() && a2dp_uipc != nullptr) {
1032 UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, nullptr);
1033 }
1034 }
1035
btif_a2dp_source_audio_tx_flush_req(void)1036 static bool btif_a2dp_source_audio_tx_flush_req(void) {
1037 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
1038
1039 btif_a2dp_source_thread.DoInThread(
1040 FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_flush_event));
1041 return true;
1042 }
1043
btif_a2dp_source_audio_readbuf(void)1044 BT_HDR* btif_a2dp_source_audio_readbuf(void) {
1045 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
1046 BT_HDR* p_buf =
1047 (BT_HDR*)fixed_queue_try_dequeue(btif_a2dp_source_cb.tx_audio_queue);
1048
1049 btif_a2dp_source_cb.stats.tx_queue_total_readbuf_calls++;
1050 btif_a2dp_source_cb.stats.tx_queue_last_readbuf_us = now_us;
1051 if (p_buf != nullptr) {
1052 // Update the statistics
1053 update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_dequeue_stats,
1054 now_us,
1055 btif_a2dp_source_cb.encoder_interval_ms * 1000);
1056 }
1057
1058 return p_buf;
1059 }
1060
log_tstamps_us(const char * comment,uint64_t timestamp_us)1061 static void log_tstamps_us(const char* comment, uint64_t timestamp_us) {
1062 static uint64_t prev_us = 0;
1063 APPL_TRACE_DEBUG("%s: [%s] ts %08" PRIu64 ", diff : %08" PRIu64
1064 ", queue sz %zu",
1065 __func__, comment, timestamp_us, timestamp_us - prev_us,
1066 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue));
1067 prev_us = timestamp_us;
1068 }
1069
update_scheduling_stats(SchedulingStats * stats,uint64_t now_us,uint64_t expected_delta)1070 static void update_scheduling_stats(SchedulingStats* stats, uint64_t now_us,
1071 uint64_t expected_delta) {
1072 uint64_t last_us = stats->last_update_us;
1073
1074 stats->total_updates++;
1075 stats->last_update_us = now_us;
1076
1077 if (last_us == 0) return; // First update: expected delta doesn't apply
1078
1079 uint64_t deadline_us = last_us + expected_delta;
1080 if (deadline_us < now_us) {
1081 // Overdue scheduling
1082 uint64_t delta_us = now_us - deadline_us;
1083 // Ignore extreme outliers
1084 if (delta_us < 10 * expected_delta) {
1085 stats->max_overdue_scheduling_delta_us =
1086 std::max(delta_us, stats->max_overdue_scheduling_delta_us);
1087 stats->total_overdue_scheduling_delta_us += delta_us;
1088 stats->overdue_scheduling_count++;
1089 stats->total_scheduling_time_us += now_us - last_us;
1090 }
1091 } else if (deadline_us > now_us) {
1092 // Premature scheduling
1093 uint64_t delta_us = deadline_us - now_us;
1094 // Ignore extreme outliers
1095 if (delta_us < 10 * expected_delta) {
1096 stats->max_premature_scheduling_delta_us =
1097 std::max(delta_us, stats->max_premature_scheduling_delta_us);
1098 stats->total_premature_scheduling_delta_us += delta_us;
1099 stats->premature_scheduling_count++;
1100 stats->total_scheduling_time_us += now_us - last_us;
1101 }
1102 } else {
1103 // On-time scheduling
1104 stats->exact_scheduling_count++;
1105 stats->total_scheduling_time_us += now_us - last_us;
1106 }
1107 }
1108
btif_a2dp_source_debug_dump(int fd)1109 void btif_a2dp_source_debug_dump(int fd) {
1110 btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
1111 &btif_a2dp_source_cb.accumulated_stats);
1112 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
1113 BtifMediaStats* accumulated_stats = &btif_a2dp_source_cb.accumulated_stats;
1114 SchedulingStats* enqueue_stats = &accumulated_stats->tx_queue_enqueue_stats;
1115 SchedulingStats* dequeue_stats = &accumulated_stats->tx_queue_dequeue_stats;
1116 size_t ave_size;
1117 uint64_t ave_time_us;
1118
1119 dprintf(fd, "\nA2DP State:\n");
1120 dprintf(fd, " TxQueue:\n");
1121
1122 dprintf(fd,
1123 " Counts (enqueue/dequeue/readbuf) : %zu / "
1124 "%zu / %zu\n",
1125 enqueue_stats->total_updates, dequeue_stats->total_updates,
1126 accumulated_stats->tx_queue_total_readbuf_calls);
1127
1128 dprintf(
1129 fd,
1130 " Last update time ago in ms (enqueue/dequeue/readbuf) : %llu / %llu "
1131 "/ %llu\n",
1132 (enqueue_stats->last_update_us > 0)
1133 ? (unsigned long long)(now_us - enqueue_stats->last_update_us) / 1000
1134 : 0,
1135 (dequeue_stats->last_update_us > 0)
1136 ? (unsigned long long)(now_us - dequeue_stats->last_update_us) / 1000
1137 : 0,
1138 (accumulated_stats->tx_queue_last_readbuf_us > 0)
1139 ? (unsigned long long)(now_us -
1140 accumulated_stats->tx_queue_last_readbuf_us) /
1141 1000
1142 : 0);
1143
1144 ave_size = 0;
1145 if (enqueue_stats->total_updates != 0)
1146 ave_size =
1147 accumulated_stats->tx_queue_total_frames / enqueue_stats->total_updates;
1148 dprintf(fd,
1149 " Frames per packet (total/max/ave) : %zu / "
1150 "%zu / %zu\n",
1151 accumulated_stats->tx_queue_total_frames,
1152 accumulated_stats->tx_queue_max_frames_per_packet, ave_size);
1153
1154 dprintf(fd,
1155 " Counts (flushed/dropped/dropouts) : %zu / "
1156 "%zu / %zu\n",
1157 accumulated_stats->tx_queue_total_flushed_messages,
1158 accumulated_stats->tx_queue_total_dropped_messages,
1159 accumulated_stats->tx_queue_dropouts);
1160
1161 dprintf(fd,
1162 " Counts (max dropped) : %zu\n",
1163 accumulated_stats->tx_queue_max_dropped_messages);
1164
1165 dprintf(
1166 fd,
1167 " Last update time ago in ms (flushed/dropped) : %llu / "
1168 "%llu\n",
1169 (accumulated_stats->tx_queue_last_flushed_us > 0)
1170 ? (unsigned long long)(now_us -
1171 accumulated_stats->tx_queue_last_flushed_us) /
1172 1000
1173 : 0,
1174 (accumulated_stats->tx_queue_last_dropouts_us > 0)
1175 ? (unsigned long long)(now_us -
1176 accumulated_stats->tx_queue_last_dropouts_us) /
1177 1000
1178 : 0);
1179
1180 dprintf(fd,
1181 " Counts (underflow) : %zu\n",
1182 accumulated_stats->media_read_total_underflow_count);
1183
1184 dprintf(fd,
1185 " Bytes (underflow) : %zu\n",
1186 accumulated_stats->media_read_total_underflow_bytes);
1187
1188 dprintf(fd,
1189 " Last update time ago in ms (underflow) : %llu\n",
1190 (accumulated_stats->media_read_last_underflow_us > 0)
1191 ? (unsigned long long)(now_us -
1192 accumulated_stats
1193 ->media_read_last_underflow_us) /
1194 1000
1195 : 0);
1196
1197 //
1198 // TxQueue enqueue stats
1199 //
1200 dprintf(
1201 fd,
1202 " Enqueue deviation counts (overdue/premature) : %zu / %zu\n",
1203 enqueue_stats->overdue_scheduling_count,
1204 enqueue_stats->premature_scheduling_count);
1205
1206 ave_time_us = 0;
1207 if (enqueue_stats->overdue_scheduling_count != 0) {
1208 ave_time_us = enqueue_stats->total_overdue_scheduling_delta_us /
1209 enqueue_stats->overdue_scheduling_count;
1210 }
1211 dprintf(
1212 fd,
1213 " Enqueue overdue scheduling time in ms (total/max/ave) : %llu / %llu "
1214 "/ %llu\n",
1215 (unsigned long long)enqueue_stats->total_overdue_scheduling_delta_us /
1216 1000,
1217 (unsigned long long)enqueue_stats->max_overdue_scheduling_delta_us / 1000,
1218 (unsigned long long)ave_time_us / 1000);
1219
1220 ave_time_us = 0;
1221 if (enqueue_stats->premature_scheduling_count != 0) {
1222 ave_time_us = enqueue_stats->total_premature_scheduling_delta_us /
1223 enqueue_stats->premature_scheduling_count;
1224 }
1225 dprintf(
1226 fd,
1227 " Enqueue premature scheduling time in ms (total/max/ave) : %llu / %llu "
1228 "/ %llu\n",
1229 (unsigned long long)enqueue_stats->total_premature_scheduling_delta_us /
1230 1000,
1231 (unsigned long long)enqueue_stats->max_premature_scheduling_delta_us /
1232 1000,
1233 (unsigned long long)ave_time_us / 1000);
1234
1235 //
1236 // TxQueue dequeue stats
1237 //
1238 dprintf(
1239 fd,
1240 " Dequeue deviation counts (overdue/premature) : %zu / %zu\n",
1241 dequeue_stats->overdue_scheduling_count,
1242 dequeue_stats->premature_scheduling_count);
1243
1244 ave_time_us = 0;
1245 if (dequeue_stats->overdue_scheduling_count != 0) {
1246 ave_time_us = dequeue_stats->total_overdue_scheduling_delta_us /
1247 dequeue_stats->overdue_scheduling_count;
1248 }
1249 dprintf(
1250 fd,
1251 " Dequeue overdue scheduling time in ms (total/max/ave) : %llu / %llu "
1252 "/ %llu\n",
1253 (unsigned long long)dequeue_stats->total_overdue_scheduling_delta_us /
1254 1000,
1255 (unsigned long long)dequeue_stats->max_overdue_scheduling_delta_us / 1000,
1256 (unsigned long long)ave_time_us / 1000);
1257
1258 ave_time_us = 0;
1259 if (dequeue_stats->premature_scheduling_count != 0) {
1260 ave_time_us = dequeue_stats->total_premature_scheduling_delta_us /
1261 dequeue_stats->premature_scheduling_count;
1262 }
1263 dprintf(
1264 fd,
1265 " Dequeue premature scheduling time in ms (total/max/ave) : %llu / %llu "
1266 "/ %llu\n",
1267 (unsigned long long)dequeue_stats->total_premature_scheduling_delta_us /
1268 1000,
1269 (unsigned long long)dequeue_stats->max_premature_scheduling_delta_us /
1270 1000,
1271 (unsigned long long)ave_time_us / 1000);
1272 }
1273
btif_a2dp_source_update_metrics(void)1274 static void btif_a2dp_source_update_metrics(void) {
1275 BtifMediaStats stats = btif_a2dp_source_cb.stats;
1276 SchedulingStats enqueue_stats = stats.tx_queue_enqueue_stats;
1277 A2dpSessionMetrics metrics;
1278 metrics.codec_index = stats.codec_index;
1279 metrics.is_a2dp_offload = btif_av_is_a2dp_offload_running();
1280 // session_start_us is 0 when btif_a2dp_source_start_audio_req() is not called
1281 // mark the metric duration as invalid (-1) in this case
1282 if (stats.session_start_us != 0) {
1283 int64_t session_end_us = stats.session_end_us == 0
1284 ? bluetooth::common::time_get_os_boottime_us()
1285 : stats.session_end_us;
1286 if (static_cast<uint64_t>(session_end_us) > stats.session_start_us) {
1287 metrics.audio_duration_ms =
1288 (session_end_us - stats.session_start_us) / 1000;
1289 }
1290 }
1291
1292 if (enqueue_stats.total_updates > 1) {
1293 metrics.media_timer_min_ms =
1294 btif_a2dp_source_cb.encoder_interval_ms -
1295 (enqueue_stats.max_premature_scheduling_delta_us / 1000);
1296 metrics.media_timer_max_ms =
1297 btif_a2dp_source_cb.encoder_interval_ms +
1298 (enqueue_stats.max_overdue_scheduling_delta_us / 1000);
1299
1300 metrics.total_scheduling_count = enqueue_stats.overdue_scheduling_count +
1301 enqueue_stats.premature_scheduling_count +
1302 enqueue_stats.exact_scheduling_count;
1303 if (metrics.total_scheduling_count > 0) {
1304 metrics.media_timer_avg_ms = enqueue_stats.total_scheduling_time_us /
1305 (1000 * metrics.total_scheduling_count);
1306 }
1307
1308 metrics.buffer_overruns_max_count = stats.tx_queue_max_dropped_messages;
1309 metrics.buffer_overruns_total = stats.tx_queue_total_dropped_messages;
1310 metrics.buffer_underruns_count = stats.media_read_total_underflow_count;
1311 metrics.buffer_underruns_average = 0;
1312 if (metrics.buffer_underruns_count > 0) {
1313 metrics.buffer_underruns_average =
1314 stats.media_read_total_underflow_bytes /
1315 metrics.buffer_underruns_count;
1316 }
1317 }
1318 BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics);
1319 }
1320
btm_read_rssi_cb(void * data)1321 static void btm_read_rssi_cb(void* data) {
1322 if (data == nullptr) {
1323 LOG_ERROR("%s: Read RSSI request timed out", __func__);
1324 return;
1325 }
1326
1327 tBTM_RSSI_RESULT* result = (tBTM_RSSI_RESULT*)data;
1328 if (result->status != BTM_SUCCESS) {
1329 LOG_ERROR("%s: unable to read remote RSSI (status %d)", __func__,
1330 result->status);
1331 return;
1332 }
1333 bluetooth::common::LogReadRssiResult(
1334 result->rem_bda, bluetooth::common::kUnknownConnectionHandle,
1335 result->hci_status, result->rssi);
1336
1337 LOG_WARN("%s: device: %s, rssi: %d", __func__,
1338 result->rem_bda.ToString().c_str(), result->rssi);
1339 }
1340
btm_read_failed_contact_counter_cb(void * data)1341 static void btm_read_failed_contact_counter_cb(void* data) {
1342 if (data == nullptr) {
1343 LOG_ERROR("%s: Read Failed Contact Counter request timed out", __func__);
1344 return;
1345 }
1346
1347 tBTM_FAILED_CONTACT_COUNTER_RESULT* result =
1348 (tBTM_FAILED_CONTACT_COUNTER_RESULT*)data;
1349 if (result->status != BTM_SUCCESS) {
1350 LOG_ERROR("%s: unable to read Failed Contact Counter (status %d)", __func__,
1351 result->status);
1352 return;
1353 }
1354 bluetooth::common::LogReadFailedContactCounterResult(
1355 result->rem_bda, bluetooth::common::kUnknownConnectionHandle,
1356 result->hci_status, result->failed_contact_counter);
1357
1358 LOG_WARN("%s: device: %s, Failed Contact Counter: %u", __func__,
1359 result->rem_bda.ToString().c_str(), result->failed_contact_counter);
1360 }
1361
btm_read_automatic_flush_timeout_cb(void * data)1362 static void btm_read_automatic_flush_timeout_cb(void* data) {
1363 if (data == nullptr) {
1364 LOG_ERROR("%s: Read Automatic Flush Timeout request timed out", __func__);
1365 return;
1366 }
1367
1368 tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT* result =
1369 (tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT*)data;
1370 if (result->status != BTM_SUCCESS) {
1371 LOG_ERROR("%s: unable to read Automatic Flush Timeout (status %d)",
1372 __func__, result->status);
1373 return;
1374 }
1375
1376 LOG_WARN("%s: device: %s, Automatic Flush Timeout: %u", __func__,
1377 result->rem_bda.ToString().c_str(), result->automatic_flush_timeout);
1378 }
1379
btm_read_tx_power_cb(void * data)1380 static void btm_read_tx_power_cb(void* data) {
1381 if (data == nullptr) {
1382 LOG_ERROR("%s: Read Tx Power request timed out", __func__);
1383 return;
1384 }
1385
1386 tBTM_TX_POWER_RESULT* result = (tBTM_TX_POWER_RESULT*)data;
1387 if (result->status != BTM_SUCCESS) {
1388 LOG_ERROR("%s: unable to read Tx Power (status %d)", __func__,
1389 result->status);
1390 return;
1391 }
1392 bluetooth::common::LogReadTxPowerLevelResult(
1393 result->rem_bda, bluetooth::common::kUnknownConnectionHandle,
1394 result->hci_status, result->tx_power);
1395
1396 LOG_WARN("%s: device: %s, Tx Power: %d", __func__,
1397 result->rem_bda.ToString().c_str(), result->tx_power);
1398 }
1399