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 #ifdef __ANDROID__
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(__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="
386 << ADDRESS_TO_LOGGABLE_STR(peer_address)
387 << " state=" << btif_a2dp_source_cb.StateStr();
388 btif_a2dp_source_setup_codec(peer_address);
389 if (btif_a2dp_source_thread.DoInThread(
390 FROM_HERE,
391 base::BindOnce(&btif_a2dp_source_start_session_delayed, peer_address,
392 std::move(peer_ready_promise)))) {
393 return true;
394 } else {
395 // cannot set promise but triggers crash
396 LOG(FATAL) << __func__ << ": peer_address="
397 << ADDRESS_TO_LOGGABLE_STR(peer_address)
398 << " state=" << btif_a2dp_source_cb.StateStr()
399 << " fails to context switch";
400 return false;
401 }
402 }
403
btif_a2dp_source_start_session_delayed(const RawAddress & peer_address,std::promise<void> peer_ready_promise)404 static void btif_a2dp_source_start_session_delayed(
405 const RawAddress& peer_address, std::promise<void> peer_ready_promise) {
406 LOG(INFO) << __func__ << ": peer_address="
407 << ADDRESS_TO_LOGGABLE_STR(peer_address)
408 << " state=" << btif_a2dp_source_cb.StateStr();
409 if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) {
410 LOG(ERROR) << __func__ << ": A2DP Source media task is not running";
411 peer_ready_promise.set_value();
412 return;
413 }
414 if (bluetooth::audio::a2dp::is_hal_enabled()) {
415 bluetooth::audio::a2dp::start_session();
416 bluetooth::audio::a2dp::set_remote_delay(btif_av_get_audio_delay());
417 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
418 bluetooth::common::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
419 } else {
420 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
421 bluetooth::common::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
422 }
423 peer_ready_promise.set_value();
424 }
425
btif_a2dp_source_restart_session(const RawAddress & old_peer_address,const RawAddress & new_peer_address,std::promise<void> peer_ready_promise)426 bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
427 const RawAddress& new_peer_address,
428 std::promise<void> peer_ready_promise) {
429 LOG(INFO) << __func__ << ": old_peer_address="
430 << ADDRESS_TO_LOGGABLE_STR(old_peer_address)
431 << " new_peer_address=" << ADDRESS_TO_LOGGABLE_STR(new_peer_address)
432 << " state=" << btif_a2dp_source_cb.StateStr();
433
434 CHECK(!new_peer_address.IsEmpty());
435
436 // Must stop first the audio streaming
437 btif_a2dp_source_stop_audio_req();
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 ADDRESS_TO_LOGGABLE_CSTR(peer_address),
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 ADDRESS_TO_LOGGABLE_CSTR(peer_address),
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
551 // This runs on worker thread
btif_a2dp_source_is_streaming(void)552 bool btif_a2dp_source_is_streaming(void) {
553 return btif_a2dp_source_cb.media_alarm.IsScheduled();
554 }
555
btif_a2dp_source_setup_codec(const RawAddress & peer_address)556 static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) {
557 LOG_INFO("%s: peer_address=%s state=%s", __func__,
558 ADDRESS_TO_LOGGABLE_CSTR(peer_address),
559 btif_a2dp_source_cb.StateStr().c_str());
560
561 // Check to make sure the platform has 8 bits/byte since
562 // we're using that in frame size calculations now.
563 CHECK(CHAR_BIT == 8);
564
565 btif_a2dp_source_audio_tx_flush_req();
566 btif_a2dp_source_thread.DoInThread(
567 FROM_HERE,
568 base::Bind(&btif_a2dp_source_setup_codec_delayed, peer_address));
569 }
570
btif_a2dp_source_setup_codec_delayed(const RawAddress & peer_address)571 static void btif_a2dp_source_setup_codec_delayed(
572 const RawAddress& peer_address) {
573 LOG_INFO("%s: peer_address=%s state=%s", __func__,
574 ADDRESS_TO_LOGGABLE_CSTR(peer_address),
575 btif_a2dp_source_cb.StateStr().c_str());
576
577 tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
578 bta_av_co_get_peer_params(peer_address, &peer_params);
579
580 if (!bta_av_co_set_active_peer(peer_address)) {
581 LOG_ERROR("%s: Cannot stream audio: cannot set active peer to %s", __func__,
582 ADDRESS_TO_LOGGABLE_CSTR(peer_address));
583 return;
584 }
585 btif_a2dp_source_cb.encoder_interface = bta_av_co_get_encoder_interface();
586 if (btif_a2dp_source_cb.encoder_interface == nullptr) {
587 LOG_ERROR("%s: Cannot stream audio: no source encoder interface", __func__);
588 return;
589 }
590
591 A2dpCodecConfig* a2dp_codec_config = bta_av_get_a2dp_current_codec();
592 if (a2dp_codec_config == nullptr) {
593 LOG_ERROR("%s: Cannot stream audio: current codec is not set", __func__);
594 return;
595 }
596
597 btif_a2dp_source_cb.encoder_interface->encoder_init(
598 &peer_params, a2dp_codec_config, btif_a2dp_source_read_callback,
599 btif_a2dp_source_enqueue_callback);
600
601 // Save a local copy of the encoder_interval_ms
602 btif_a2dp_source_cb.encoder_interval_ms =
603 btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms();
604
605 if (bluetooth::audio::a2dp::is_hal_enabled()) {
606 bluetooth::audio::a2dp::setup_codec();
607 }
608 }
609
btif_a2dp_source_cleanup_codec()610 static void btif_a2dp_source_cleanup_codec() {
611 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
612 // Must stop media task first before cleaning up the encoder
613 btif_a2dp_source_stop_audio_req();
614 btif_a2dp_source_thread.DoInThread(
615 FROM_HERE, base::Bind(&btif_a2dp_source_cleanup_codec_delayed));
616 }
617
btif_a2dp_source_cleanup_codec_delayed()618 static void btif_a2dp_source_cleanup_codec_delayed() {
619 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
620 if (btif_a2dp_source_cb.encoder_interface != nullptr) {
621 btif_a2dp_source_cb.encoder_interface->encoder_cleanup();
622 btif_a2dp_source_cb.encoder_interface = nullptr;
623 }
624 }
625
btif_a2dp_source_start_audio_req(void)626 void btif_a2dp_source_start_audio_req(void) {
627 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
628
629 btif_a2dp_source_thread.DoInThread(
630 FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_start_event));
631 }
632
btif_a2dp_source_stop_audio_req(void)633 void btif_a2dp_source_stop_audio_req(void) {
634 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
635
636 btif_a2dp_source_thread.DoInThread(
637 FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_stop_event));
638 }
639
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)640 void btif_a2dp_source_encoder_user_config_update_req(
641 const RawAddress& peer_address,
642 const std::vector<btav_a2dp_codec_config_t>& codec_user_preferences,
643 std::promise<void> peer_ready_promise) {
644 LOG(INFO) << __func__ << ": peer_address="
645 << ADDRESS_TO_LOGGABLE_STR(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="
655 << ADDRESS_TO_LOGGABLE_STR(peer_address)
656 << " state=" << btif_a2dp_source_cb.StateStr()
657 << " fails to context switch";
658 }
659 }
660
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)661 static void btif_a2dp_source_encoder_user_config_update_event(
662 const RawAddress& peer_address,
663 const std::vector<btav_a2dp_codec_config_t>& codec_user_preferences,
664 std::promise<void> peer_ready_promise) {
665 bool restart_output = false;
666 bool success = false;
667 for (auto codec_user_config : codec_user_preferences) {
668 success = bta_av_co_set_codec_user_config(peer_address, codec_user_config,
669 &restart_output);
670 if (success) {
671 LOG(INFO) << __func__ << ": peer_address="
672 << ADDRESS_TO_LOGGABLE_STR(peer_address)
673 << " state=" << btif_a2dp_source_cb.StateStr()
674 << " codec_preference={" << codec_user_config.ToString()
675 << "} restart_output=" << (restart_output ? "true" : "false");
676 break;
677 }
678 }
679 if (success && restart_output) {
680 // Codec reconfiguration is in progress, and it is safe to unlock since
681 // remaining tasks like starting audio session and reporting new codec
682 // will be handled by BTA_AV_RECONFIG_EVT later.
683 peer_ready_promise.set_value();
684 return;
685 }
686 if (!success) {
687 LOG(ERROR) << __func__ << ": cannot update codec user configuration(s)";
688 }
689 if (!peer_address.IsEmpty() && peer_address == btif_av_source_active_peer()) {
690 // No more actions needed with remote, and if succeed, user had changed the
691 // config like the bits per sample only. Let's resume the session now.
692 btif_a2dp_source_start_session(peer_address, std::move(peer_ready_promise));
693 } else {
694 // Unlock for non-active peer
695 peer_ready_promise.set_value();
696 }
697 }
698
btif_a2dp_source_feeding_update_req(const btav_a2dp_codec_config_t & codec_audio_config)699 void btif_a2dp_source_feeding_update_req(
700 const btav_a2dp_codec_config_t& codec_audio_config) {
701 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
702 btif_a2dp_source_thread.DoInThread(
703 FROM_HERE, base::Bind(&btif_a2dp_source_audio_feeding_update_event,
704 codec_audio_config));
705 }
706
btif_a2dp_source_audio_feeding_update_event(const btav_a2dp_codec_config_t & codec_audio_config)707 static void btif_a2dp_source_audio_feeding_update_event(
708 const btav_a2dp_codec_config_t& codec_audio_config) {
709 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
710 if (!bta_av_co_set_codec_audio_config(codec_audio_config)) {
711 LOG_ERROR("%s: cannot update codec audio feeding parameters", __func__);
712 }
713 }
714
btif_a2dp_source_on_idle(void)715 void btif_a2dp_source_on_idle(void) {
716 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
717 if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return;
718
719 /* Make sure media task is stopped */
720 btif_a2dp_source_stop_audio_req();
721 }
722
btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND * p_av_suspend)723 void btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
724 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
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 {
740 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_SUCCESS);
741 return;
742 }
743
744 if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return;
745
746 // ensure tx frames are immediately suspended
747 btif_a2dp_source_cb.tx_flush = true;
748 // ensure tx frames are immediately flushed
749 btif_a2dp_source_audio_tx_flush_req();
750
751 // request to stop media task
752 btif_a2dp_source_stop_audio_req();
753
754 // once software stream is fully stopped we will ack back
755 }
756
btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND * p_av_suspend)757 void btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
758 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
759
760 if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return;
761
762 CHECK(p_av_suspend != nullptr) << "Suspend result could not be nullptr";
763
764 // check for status failures
765 if (p_av_suspend->status != BTA_AV_SUCCESS) {
766 LOG_WARN("%s: A2DP suspend failed: status=%d, initiator=%s", __func__,
767 p_av_suspend->status,
768 (p_av_suspend->initiator ? "true" : "false"));
769 if (p_av_suspend->initiator) {
770 if (bluetooth::audio::a2dp::is_hal_enabled()) {
771 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_FAILURE);
772 } else {
773 btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
774 }
775 }
776 } else if (btif_av_is_a2dp_offload_running()) {
777 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_SUCCESS);
778 return;
779 }
780
781 // ensure tx frames are immediately suspended
782 btif_a2dp_source_cb.tx_flush = true;
783
784 // stop timer tick
785 btif_a2dp_source_stop_audio_req();
786
787 // once software stream is fully stopped we will ack back
788 }
789
790 /* when true media task discards any tx frames */
btif_a2dp_source_set_tx_flush(bool enable)791 void btif_a2dp_source_set_tx_flush(bool enable) {
792 LOG_INFO("%s: enable=%s state=%s", __func__, (enable) ? "true" : "false",
793 btif_a2dp_source_cb.StateStr().c_str());
794 btif_a2dp_source_cb.tx_flush = enable;
795 }
796
btif_a2dp_source_audio_tx_start_event(void)797 static void btif_a2dp_source_audio_tx_start_event(void) {
798 LOG_INFO("%s: streaming %s state=%s", __func__,
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("%s: streaming %s state=%s", __func__,
844 btif_a2dp_source_is_streaming() ? "true" : "false",
845 btif_a2dp_source_cb.StateStr().c_str());
846
847 if (btif_av_is_a2dp_offload_running()) return;
848 if (!btif_a2dp_source_is_streaming()) return;
849
850 btif_a2dp_source_cb.stats.session_end_us =
851 bluetooth::common::time_get_os_boottime_us();
852 btif_a2dp_source_update_metrics();
853 btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
854 &btif_a2dp_source_cb.accumulated_stats);
855
856 uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
857
858 // Keep track of audio data still left in the pipe
859 if (bluetooth::audio::a2dp::is_hal_enabled()) {
860 btif_a2dp_control_log_bytes_read(
861 bluetooth::audio::a2dp::read(p_buf, sizeof(p_buf)));
862 } else if (a2dp_uipc != nullptr) {
863 btif_a2dp_control_log_bytes_read(
864 UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, sizeof(p_buf)));
865 }
866
867 /* Stop the timer first */
868 btif_a2dp_source_cb.media_alarm.CancelAndWait();
869 wakelock_release();
870
871 if (bluetooth::audio::a2dp::is_hal_enabled()) {
872 bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_SUCCESS);
873 } else if (a2dp_uipc != nullptr) {
874 UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO);
875
876 /*
877 * Try to send acknowledgement once the media stream is
878 * stopped. This will make sure that the A2DP HAL layer is
879 * un-blocked on wait for acknowledgment for the sent command.
880 * This resolves a corner cases AVDTP SUSPEND collision
881 * when the DUT and the remote device issue SUSPEND simultaneously
882 * and due to the processing of the SUSPEND request from the remote,
883 * the media path is torn down. If the A2DP HAL happens to wait
884 * for ACK for the initiated SUSPEND, it would never receive it casuing
885 * a block/wait. Due to this acknowledgement, the A2DP HAL is guranteed
886 * to get the ACK for any pending command in such cases.
887 */
888
889 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
890 }
891
892 /* audio engine stopped, reset tx suspended flag */
893 btif_a2dp_source_cb.tx_flush = false;
894
895 /* Reset the media feeding state */
896 if (btif_a2dp_source_cb.encoder_interface != nullptr)
897 btif_a2dp_source_cb.encoder_interface->feeding_reset();
898 }
899
btif_a2dp_source_audio_handle_timer(void)900 static void btif_a2dp_source_audio_handle_timer(void) {
901 if (btif_av_is_a2dp_offload_running()) return;
902
903 #ifndef TARGET_FLOSS
904 uint64_t timestamp_us = bluetooth::common::time_get_os_boottime_us();
905 uint64_t stats_timestamp_us = timestamp_us;
906 #else
907 uint64_t timestamp_us = bluetooth::common::time_get_os_monotonic_raw_us();
908 uint64_t stats_timestamp_us = bluetooth::common::time_get_os_boottime_us();
909 #endif
910
911 log_tstamps_us("A2DP Source tx scheduling timer", timestamp_us);
912
913 if (!btif_a2dp_source_is_streaming()) {
914 LOG_ERROR("%s: ERROR Media task Scheduled after Suspend", __func__);
915 return;
916 }
917 CHECK(btif_a2dp_source_cb.encoder_interface != nullptr);
918 size_t transmit_queue_length =
919 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
920 #ifdef __ANDROID__
921 ATRACE_INT("btif TX queue", transmit_queue_length);
922 #endif
923 if (btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length !=
924 nullptr) {
925 btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length(
926 transmit_queue_length);
927 }
928 btif_a2dp_source_cb.encoder_interface->send_frames(timestamp_us);
929 bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
930 update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_enqueue_stats,
931 stats_timestamp_us,
932 btif_a2dp_source_cb.encoder_interval_ms * 1000);
933 }
934
btif_a2dp_source_read_callback(uint8_t * p_buf,uint32_t len)935 static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) {
936 uint32_t bytes_read = 0;
937
938 if (bluetooth::audio::a2dp::is_hal_enabled()) {
939 bytes_read = bluetooth::audio::a2dp::read(p_buf, len);
940 } else if (a2dp_uipc != nullptr) {
941 bytes_read = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, len);
942 }
943
944 if (bytes_read < len) {
945 LOG_WARN("%s: UNDERFLOW: ONLY READ %d BYTES OUT OF %d", __func__,
946 bytes_read, len);
947 btif_a2dp_source_cb.stats.media_read_total_underflow_bytes +=
948 (len - bytes_read);
949 btif_a2dp_source_cb.stats.media_read_total_underflow_count++;
950 btif_a2dp_source_cb.stats.media_read_last_underflow_us =
951 bluetooth::common::time_get_os_boottime_us();
952 log_a2dp_audio_underrun_event(btif_av_source_active_peer(),
953 btif_a2dp_source_cb.encoder_interval_ms,
954 len - bytes_read);
955 }
956
957 return bytes_read;
958 }
959
btif_a2dp_source_enqueue_callback(BT_HDR * p_buf,size_t frames_n,uint32_t bytes_read)960 static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n,
961 uint32_t bytes_read) {
962 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
963 btif_a2dp_control_log_bytes_read(bytes_read);
964
965 /* Check if timer was stopped (media task stopped) */
966 if (!btif_a2dp_source_is_streaming()) {
967 osi_free(p_buf);
968 return false;
969 }
970
971 /* Check if the transmission queue has been flushed */
972 if (btif_a2dp_source_cb.tx_flush) {
973 LOG_VERBOSE("%s: tx suspended, discarded frame", __func__);
974
975 btif_a2dp_source_cb.stats.tx_queue_total_flushed_messages +=
976 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
977 btif_a2dp_source_cb.stats.tx_queue_last_flushed_us = now_us;
978 fixed_queue_flush(btif_a2dp_source_cb.tx_audio_queue, osi_free);
979
980 osi_free(p_buf);
981 return false;
982 }
983
984 // Check for TX queue overflow
985 // TODO: Using frames_n here is probably wrong: should be "+ 1" instead.
986 if (fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue) + frames_n >
987 btif_a2dp_source_dynamic_audio_buffer_size) {
988 LOG_WARN("%s: TX queue buffer size now=%u adding=%u max=%d", __func__,
989 (uint32_t)fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue),
990 (uint32_t)frames_n, btif_a2dp_source_dynamic_audio_buffer_size);
991 // Keep track of drop-outs
992 btif_a2dp_source_cb.stats.tx_queue_dropouts++;
993 btif_a2dp_source_cb.stats.tx_queue_last_dropouts_us = now_us;
994
995 // Flush all queued buffers
996 size_t drop_n = fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
997 btif_a2dp_source_cb.stats.tx_queue_max_dropped_messages = std::max(
998 drop_n, btif_a2dp_source_cb.stats.tx_queue_max_dropped_messages);
999 int num_dropped_encoded_bytes = 0;
1000 int num_dropped_encoded_frames = 0;
1001 while (fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue)) {
1002 btif_a2dp_source_cb.stats.tx_queue_total_dropped_messages++;
1003 void* p_data =
1004 fixed_queue_try_dequeue(btif_a2dp_source_cb.tx_audio_queue);
1005 if (p_data != nullptr) {
1006 auto p_dropped_buf = static_cast<BT_HDR*>(p_data);
1007 num_dropped_encoded_bytes += p_dropped_buf->len;
1008 num_dropped_encoded_frames += p_dropped_buf->layer_specific;
1009 osi_free(p_data);
1010 }
1011 }
1012 log_a2dp_audio_overrun_event(
1013 btif_av_source_active_peer(), btif_a2dp_source_cb.encoder_interval_ms,
1014 drop_n, num_dropped_encoded_frames, num_dropped_encoded_bytes);
1015
1016 // Intel controllers don't handle ReadRSSI, ReadFailedContactCounter, and
1017 // ReadTxPower very well, it sends back Hardware Error event which will
1018 // crash the daemon. So temporarily disable this for Floss.
1019 // TODO(b/249876976): Intel controllers to handle this command correctly.
1020 // And if the need for disabling metrics-related HCI call grows, consider
1021 // creating a framework to avoid ifdefs.
1022 #ifndef TARGET_FLOSS
1023 // Request additional debug info if we had to flush buffers
1024 RawAddress peer_bda = btif_av_source_active_peer();
1025 tBTM_STATUS status = BTM_ReadRSSI(peer_bda, btm_read_rssi_cb);
1026 if (status != BTM_CMD_STARTED) {
1027 LOG_WARN("%s: Cannot read RSSI: status %d", __func__, status);
1028 }
1029
1030 status = BTM_ReadFailedContactCounter(peer_bda,
1031 btm_read_failed_contact_counter_cb);
1032 if (status != BTM_CMD_STARTED) {
1033 LOG_WARN("%s: Cannot read Failed Contact Counter: status %d", __func__,
1034 status);
1035 }
1036
1037 status =
1038 BTM_ReadTxPower(peer_bda, BT_TRANSPORT_BR_EDR, btm_read_tx_power_cb);
1039 if (status != BTM_CMD_STARTED) {
1040 LOG_WARN("%s: Cannot read Tx Power: status %d", __func__, status);
1041 }
1042 #endif
1043 }
1044
1045 /* Update the statistics */
1046 btif_a2dp_source_cb.stats.tx_queue_total_frames += frames_n;
1047 btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet = std::max(
1048 frames_n, btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet);
1049 CHECK(btif_a2dp_source_cb.encoder_interface != nullptr);
1050
1051 fixed_queue_enqueue(btif_a2dp_source_cb.tx_audio_queue, p_buf);
1052
1053 return true;
1054 }
1055
btif_a2dp_source_audio_tx_flush_event(void)1056 static void btif_a2dp_source_audio_tx_flush_event(void) {
1057 /* Flush all enqueued audio buffers (encoded) */
1058 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
1059 if (btif_av_is_a2dp_offload_running()) return;
1060
1061 if (btif_a2dp_source_cb.encoder_interface != nullptr)
1062 btif_a2dp_source_cb.encoder_interface->feeding_flush();
1063
1064 btif_a2dp_source_cb.stats.tx_queue_total_flushed_messages +=
1065 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
1066 btif_a2dp_source_cb.stats.tx_queue_last_flushed_us =
1067 bluetooth::common::time_get_os_boottime_us();
1068 fixed_queue_flush(btif_a2dp_source_cb.tx_audio_queue, osi_free);
1069
1070 if (!bluetooth::audio::a2dp::is_hal_enabled() && a2dp_uipc != nullptr) {
1071 UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, nullptr);
1072 }
1073 }
1074
btif_a2dp_source_audio_tx_flush_req(void)1075 static bool btif_a2dp_source_audio_tx_flush_req(void) {
1076 LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str());
1077
1078 btif_a2dp_source_thread.DoInThread(
1079 FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_flush_event));
1080 return true;
1081 }
1082
btif_a2dp_source_audio_readbuf(void)1083 BT_HDR* btif_a2dp_source_audio_readbuf(void) {
1084 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
1085 BT_HDR* p_buf =
1086 (BT_HDR*)fixed_queue_try_dequeue(btif_a2dp_source_cb.tx_audio_queue);
1087
1088 btif_a2dp_source_cb.stats.tx_queue_total_readbuf_calls++;
1089 btif_a2dp_source_cb.stats.tx_queue_last_readbuf_us = now_us;
1090 if (p_buf != nullptr) {
1091 // Update the statistics
1092 update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_dequeue_stats,
1093 now_us,
1094 btif_a2dp_source_cb.encoder_interval_ms * 1000);
1095 }
1096
1097 return p_buf;
1098 }
1099
log_tstamps_us(const char * comment,uint64_t timestamp_us)1100 static void log_tstamps_us(const char* comment, uint64_t timestamp_us) {
1101 static uint64_t prev_us = 0;
1102 APPL_TRACE_DEBUG("%s: [%s] ts %08" PRIu64 ", diff : %08" PRIu64
1103 ", queue sz %zu",
1104 __func__, comment, timestamp_us, timestamp_us - prev_us,
1105 fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue));
1106 prev_us = timestamp_us;
1107 }
1108
update_scheduling_stats(SchedulingStats * stats,uint64_t now_us,uint64_t expected_delta)1109 static void update_scheduling_stats(SchedulingStats* stats, uint64_t now_us,
1110 uint64_t expected_delta) {
1111 uint64_t last_us = stats->last_update_us;
1112
1113 stats->total_updates++;
1114 stats->last_update_us = now_us;
1115
1116 if (last_us == 0) return; // First update: expected delta doesn't apply
1117
1118 uint64_t deadline_us = last_us + expected_delta;
1119 if (deadline_us < now_us) {
1120 // Overdue scheduling
1121 uint64_t delta_us = now_us - deadline_us;
1122 // Ignore extreme outliers
1123 if (delta_us < 10 * expected_delta) {
1124 stats->max_overdue_scheduling_delta_us =
1125 std::max(delta_us, stats->max_overdue_scheduling_delta_us);
1126 stats->total_overdue_scheduling_delta_us += delta_us;
1127 stats->overdue_scheduling_count++;
1128 stats->total_scheduling_time_us += now_us - last_us;
1129 }
1130 } else if (deadline_us > now_us) {
1131 // Premature scheduling
1132 uint64_t delta_us = deadline_us - now_us;
1133 // Ignore extreme outliers
1134 if (delta_us < 10 * expected_delta) {
1135 stats->max_premature_scheduling_delta_us =
1136 std::max(delta_us, stats->max_premature_scheduling_delta_us);
1137 stats->total_premature_scheduling_delta_us += delta_us;
1138 stats->premature_scheduling_count++;
1139 stats->total_scheduling_time_us += now_us - last_us;
1140 }
1141 } else {
1142 // On-time scheduling
1143 stats->exact_scheduling_count++;
1144 stats->total_scheduling_time_us += now_us - last_us;
1145 }
1146 }
1147
btif_a2dp_source_debug_dump(int fd)1148 void btif_a2dp_source_debug_dump(int fd) {
1149 btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
1150 &btif_a2dp_source_cb.accumulated_stats);
1151 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
1152 BtifMediaStats* accumulated_stats = &btif_a2dp_source_cb.accumulated_stats;
1153 SchedulingStats* enqueue_stats = &accumulated_stats->tx_queue_enqueue_stats;
1154 SchedulingStats* dequeue_stats = &accumulated_stats->tx_queue_dequeue_stats;
1155 size_t ave_size;
1156 uint64_t ave_time_us;
1157
1158 dprintf(fd, "\nA2DP State:\n");
1159 dprintf(fd, " TxQueue:\n");
1160
1161 dprintf(fd,
1162 " Counts (enqueue/dequeue/readbuf) : %zu / "
1163 "%zu / %zu\n",
1164 enqueue_stats->total_updates, dequeue_stats->total_updates,
1165 accumulated_stats->tx_queue_total_readbuf_calls);
1166
1167 dprintf(
1168 fd,
1169 " Last update time ago in ms (enqueue/dequeue/readbuf) : %llu / %llu "
1170 "/ %llu\n",
1171 (enqueue_stats->last_update_us > 0)
1172 ? (unsigned long long)(now_us - enqueue_stats->last_update_us) / 1000
1173 : 0,
1174 (dequeue_stats->last_update_us > 0)
1175 ? (unsigned long long)(now_us - dequeue_stats->last_update_us) / 1000
1176 : 0,
1177 (accumulated_stats->tx_queue_last_readbuf_us > 0)
1178 ? (unsigned long long)(now_us -
1179 accumulated_stats->tx_queue_last_readbuf_us) /
1180 1000
1181 : 0);
1182
1183 ave_size = 0;
1184 if (enqueue_stats->total_updates != 0)
1185 ave_size =
1186 accumulated_stats->tx_queue_total_frames / enqueue_stats->total_updates;
1187 dprintf(fd,
1188 " Frames per packet (total/max/ave) : %zu / "
1189 "%zu / %zu\n",
1190 accumulated_stats->tx_queue_total_frames,
1191 accumulated_stats->tx_queue_max_frames_per_packet, ave_size);
1192
1193 dprintf(fd,
1194 " Counts (flushed/dropped/dropouts) : %zu / "
1195 "%zu / %zu\n",
1196 accumulated_stats->tx_queue_total_flushed_messages,
1197 accumulated_stats->tx_queue_total_dropped_messages,
1198 accumulated_stats->tx_queue_dropouts);
1199
1200 dprintf(fd,
1201 " Counts (max dropped) : %zu\n",
1202 accumulated_stats->tx_queue_max_dropped_messages);
1203
1204 dprintf(
1205 fd,
1206 " Last update time ago in ms (flushed/dropped) : %llu / "
1207 "%llu\n",
1208 (accumulated_stats->tx_queue_last_flushed_us > 0)
1209 ? (unsigned long long)(now_us -
1210 accumulated_stats->tx_queue_last_flushed_us) /
1211 1000
1212 : 0,
1213 (accumulated_stats->tx_queue_last_dropouts_us > 0)
1214 ? (unsigned long long)(now_us -
1215 accumulated_stats->tx_queue_last_dropouts_us) /
1216 1000
1217 : 0);
1218
1219 dprintf(fd,
1220 " Counts (underflow) : %zu\n",
1221 accumulated_stats->media_read_total_underflow_count);
1222
1223 dprintf(fd,
1224 " Bytes (underflow) : %zu\n",
1225 accumulated_stats->media_read_total_underflow_bytes);
1226
1227 dprintf(fd,
1228 " Last update time ago in ms (underflow) : %llu\n",
1229 (accumulated_stats->media_read_last_underflow_us > 0)
1230 ? (unsigned long long)(now_us -
1231 accumulated_stats
1232 ->media_read_last_underflow_us) /
1233 1000
1234 : 0);
1235
1236 //
1237 // TxQueue enqueue stats
1238 //
1239 dprintf(
1240 fd,
1241 " Enqueue deviation counts (overdue/premature) : %zu / %zu\n",
1242 enqueue_stats->overdue_scheduling_count,
1243 enqueue_stats->premature_scheduling_count);
1244
1245 ave_time_us = 0;
1246 if (enqueue_stats->overdue_scheduling_count != 0) {
1247 ave_time_us = enqueue_stats->total_overdue_scheduling_delta_us /
1248 enqueue_stats->overdue_scheduling_count;
1249 }
1250 dprintf(
1251 fd,
1252 " Enqueue overdue scheduling time in ms (total/max/ave) : %llu / %llu "
1253 "/ %llu\n",
1254 (unsigned long long)enqueue_stats->total_overdue_scheduling_delta_us /
1255 1000,
1256 (unsigned long long)enqueue_stats->max_overdue_scheduling_delta_us / 1000,
1257 (unsigned long long)ave_time_us / 1000);
1258
1259 ave_time_us = 0;
1260 if (enqueue_stats->premature_scheduling_count != 0) {
1261 ave_time_us = enqueue_stats->total_premature_scheduling_delta_us /
1262 enqueue_stats->premature_scheduling_count;
1263 }
1264 dprintf(
1265 fd,
1266 " Enqueue premature scheduling time in ms (total/max/ave) : %llu / %llu "
1267 "/ %llu\n",
1268 (unsigned long long)enqueue_stats->total_premature_scheduling_delta_us /
1269 1000,
1270 (unsigned long long)enqueue_stats->max_premature_scheduling_delta_us /
1271 1000,
1272 (unsigned long long)ave_time_us / 1000);
1273
1274 //
1275 // TxQueue dequeue stats
1276 //
1277 dprintf(
1278 fd,
1279 " Dequeue deviation counts (overdue/premature) : %zu / %zu\n",
1280 dequeue_stats->overdue_scheduling_count,
1281 dequeue_stats->premature_scheduling_count);
1282
1283 ave_time_us = 0;
1284 if (dequeue_stats->overdue_scheduling_count != 0) {
1285 ave_time_us = dequeue_stats->total_overdue_scheduling_delta_us /
1286 dequeue_stats->overdue_scheduling_count;
1287 }
1288 dprintf(
1289 fd,
1290 " Dequeue overdue scheduling time in ms (total/max/ave) : %llu / %llu "
1291 "/ %llu\n",
1292 (unsigned long long)dequeue_stats->total_overdue_scheduling_delta_us /
1293 1000,
1294 (unsigned long long)dequeue_stats->max_overdue_scheduling_delta_us / 1000,
1295 (unsigned long long)ave_time_us / 1000);
1296
1297 ave_time_us = 0;
1298 if (dequeue_stats->premature_scheduling_count != 0) {
1299 ave_time_us = dequeue_stats->total_premature_scheduling_delta_us /
1300 dequeue_stats->premature_scheduling_count;
1301 }
1302 dprintf(
1303 fd,
1304 " Dequeue premature scheduling time in ms (total/max/ave) : %llu / %llu "
1305 "/ %llu\n",
1306 (unsigned long long)dequeue_stats->total_premature_scheduling_delta_us /
1307 1000,
1308 (unsigned long long)dequeue_stats->max_premature_scheduling_delta_us /
1309 1000,
1310 (unsigned long long)ave_time_us / 1000);
1311 }
1312
btif_a2dp_source_update_metrics(void)1313 static void btif_a2dp_source_update_metrics(void) {
1314 BtifMediaStats stats = btif_a2dp_source_cb.stats;
1315 SchedulingStats enqueue_stats = stats.tx_queue_enqueue_stats;
1316 A2dpSessionMetrics metrics;
1317 metrics.codec_index = stats.codec_index;
1318 metrics.is_a2dp_offload = btif_av_is_a2dp_offload_running();
1319 // session_start_us is 0 when btif_a2dp_source_start_audio_req() is not called
1320 // mark the metric duration as invalid (-1) in this case
1321 if (stats.session_start_us != 0) {
1322 int64_t session_end_us = stats.session_end_us == 0
1323 ? bluetooth::common::time_get_os_boottime_us()
1324 : stats.session_end_us;
1325 if (static_cast<uint64_t>(session_end_us) > stats.session_start_us) {
1326 metrics.audio_duration_ms =
1327 (session_end_us - stats.session_start_us) / 1000;
1328 }
1329 }
1330
1331 if (enqueue_stats.total_updates > 1) {
1332 metrics.media_timer_min_ms =
1333 btif_a2dp_source_cb.encoder_interval_ms -
1334 (enqueue_stats.max_premature_scheduling_delta_us / 1000);
1335 metrics.media_timer_max_ms =
1336 btif_a2dp_source_cb.encoder_interval_ms +
1337 (enqueue_stats.max_overdue_scheduling_delta_us / 1000);
1338
1339 metrics.total_scheduling_count = enqueue_stats.overdue_scheduling_count +
1340 enqueue_stats.premature_scheduling_count +
1341 enqueue_stats.exact_scheduling_count;
1342 if (metrics.total_scheduling_count > 0) {
1343 metrics.media_timer_avg_ms = enqueue_stats.total_scheduling_time_us /
1344 (1000 * metrics.total_scheduling_count);
1345 }
1346
1347 metrics.buffer_overruns_max_count = stats.tx_queue_max_dropped_messages;
1348 metrics.buffer_overruns_total = stats.tx_queue_total_dropped_messages;
1349 metrics.buffer_underruns_count = stats.media_read_total_underflow_count;
1350 metrics.buffer_underruns_average = 0;
1351 if (metrics.buffer_underruns_count > 0) {
1352 metrics.buffer_underruns_average =
1353 (float)stats.media_read_total_underflow_bytes /
1354 metrics.buffer_underruns_count;
1355 }
1356 }
1357 BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics);
1358 }
1359
btif_a2dp_source_set_dynamic_audio_buffer_size(uint8_t dynamic_audio_buffer_size)1360 void btif_a2dp_source_set_dynamic_audio_buffer_size(
1361 uint8_t dynamic_audio_buffer_size) {
1362 btif_a2dp_source_dynamic_audio_buffer_size = dynamic_audio_buffer_size;
1363 }
1364
btm_read_rssi_cb(void * data)1365 static void btm_read_rssi_cb(void* data) {
1366 if (data == nullptr) {
1367 LOG_ERROR("%s: Read RSSI request timed out", __func__);
1368 return;
1369 }
1370
1371 tBTM_RSSI_RESULT* result = (tBTM_RSSI_RESULT*)data;
1372 if (result->status != BTM_SUCCESS) {
1373 LOG_ERROR("%s: unable to read remote RSSI (status %d)", __func__,
1374 result->status);
1375 return;
1376 }
1377
1378 log_read_rssi_result(result->rem_bda,
1379 bluetooth::common::kUnknownConnectionHandle,
1380 result->hci_status, result->rssi);
1381
1382 LOG_WARN("%s: device: %s, rssi: %d", __func__,
1383 ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), result->rssi);
1384 }
1385
btm_read_failed_contact_counter_cb(void * data)1386 static void btm_read_failed_contact_counter_cb(void* data) {
1387 if (data == nullptr) {
1388 LOG_ERROR("%s: Read Failed Contact Counter request timed out", __func__);
1389 return;
1390 }
1391
1392 tBTM_FAILED_CONTACT_COUNTER_RESULT* result =
1393 (tBTM_FAILED_CONTACT_COUNTER_RESULT*)data;
1394 if (result->status != BTM_SUCCESS) {
1395 LOG_ERROR("%s: unable to read Failed Contact Counter (status %d)", __func__,
1396 result->status);
1397 return;
1398 }
1399 log_read_failed_contact_counter_result(
1400 result->rem_bda, bluetooth::common::kUnknownConnectionHandle,
1401 result->hci_status, result->failed_contact_counter);
1402
1403 LOG_WARN("%s: device: %s, Failed Contact Counter: %u", __func__,
1404 ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda),
1405 result->failed_contact_counter);
1406 }
1407
btm_read_tx_power_cb(void * data)1408 static void btm_read_tx_power_cb(void* data) {
1409 if (data == nullptr) {
1410 LOG_ERROR("%s: Read Tx Power request timed out", __func__);
1411 return;
1412 }
1413
1414 tBTM_TX_POWER_RESULT* result = (tBTM_TX_POWER_RESULT*)data;
1415 if (result->status != BTM_SUCCESS) {
1416 LOG_ERROR("%s: unable to read Tx Power (status %d)", __func__,
1417 result->status);
1418 return;
1419 }
1420 log_read_tx_power_level_result(result->rem_bda,
1421 bluetooth::common::kUnknownConnectionHandle,
1422 result->hci_status, result->tx_power);
1423
1424 LOG_WARN("%s: device: %s, Tx Power: %d", __func__,
1425 ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), result->tx_power);
1426 }
1427