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