1 /******************************************************************************
2 *
3 * Copyright (C) 2017 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "btif_a2dp_audio_interface"
20
21 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioHost.h>
22 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioOffload.h>
23 #include <android/hardware/bluetooth/a2dp/1.0/types.h>
24 #include <base/bind.h>
25 #include <base/callback.h>
26 #include <base/location.h>
27 #include <hwbinder/ProcessState.h>
28 #include <mutex>
29
30 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
31 #include "bta/av/bta_av_int.h"
32 #include "bta/include/bta_av_api.h"
33 #include "btif/include/btif_a2dp_source.h"
34 #include "btif/include/btif_av.h"
35 #include "btif/include/btif_av_co.h"
36 #include "btif/include/btif_hf.h"
37 #include "common/metrics.h"
38 #include "common/time_util.h"
39 #include "osi/include/log.h"
40 #include "stack/include/a2dp_codec_api.h"
41 #include "stack/include/avdt_api.h"
42 #include "stack/include/btu.h" // do_in_main_thread
43
44 using bluetooth::common::A2dpSessionMetrics;
45 using bluetooth::common::BluetoothMetricsLogger;
46
47 using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload;
48 using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost;
49 using android::hardware::bluetooth::a2dp::V1_0::Status;
50 using android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration;
51 using android::hardware::bluetooth::a2dp::V1_0::CodecType;
52 using android::hardware::bluetooth::a2dp::V1_0::SampleRate;
53 using android::hardware::bluetooth::a2dp::V1_0::BitsPerSample;
54 using android::hardware::bluetooth::a2dp::V1_0::ChannelMode;
55 using android::hardware::ProcessState;
56 using ::android::hardware::Return;
57 using ::android::hardware::Void;
58 using ::android::hardware::hidl_death_recipient;
59 using ::android::hardware::hidl_vec;
60 using ::android::sp;
61 using ::android::wp;
62 android::sp<IBluetoothAudioOffload> btAudio;
63
64 #define CASE_RETURN_STR(const) \
65 case const: \
66 return #const;
67 static uint8_t a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
68 static Status mapToStatus(uint8_t resp);
69 uint8_t btif_a2dp_audio_process_request(uint8_t cmd);
70
71 static void btif_a2dp_audio_send_start_req();
72 static void btif_a2dp_audio_send_suspend_req();
73 static void btif_a2dp_audio_send_stop_req();
74 static void btif_a2dp_audio_interface_init();
75 static void btif_a2dp_audio_interface_deinit();
76 static void btif_a2dp_audio_interface_restart_session();
77 // Delay reporting
78 // static void btif_a2dp_audio_send_sink_latency();
79
80 class A2dpOffloadAudioStats {
81 public:
A2dpOffloadAudioStats()82 A2dpOffloadAudioStats() { Reset(); }
Reset()83 void Reset() {
84 std::lock_guard<std::recursive_mutex> lock(lock_);
85 ResetPreserveSession();
86 codec_index_ = -1;
87 }
ResetPreserveSession()88 void ResetPreserveSession() {
89 std::lock_guard<std::recursive_mutex> lock(lock_);
90 audio_start_time_ms_ = -1;
91 audio_stop_time_ms_ = -1;
92 }
StoreMetrics()93 void StoreMetrics() {
94 std::lock_guard<std::recursive_mutex> lock(lock_);
95 if (audio_start_time_ms_ < 0 || audio_stop_time_ms_ < 0) {
96 return;
97 }
98 A2dpSessionMetrics metrics;
99 metrics.codec_index = codec_index_;
100 metrics.is_a2dp_offload = true;
101 if (audio_stop_time_ms_ > audio_start_time_ms_) {
102 metrics.audio_duration_ms = audio_stop_time_ms_ - audio_start_time_ms_;
103 }
104 BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics);
105 }
LogAudioStart()106 void LogAudioStart() {
107 std::lock_guard<std::recursive_mutex> lock(lock_);
108 audio_start_time_ms_ = bluetooth::common::time_get_os_boottime_ms();
109 }
LogAudioStop()110 void LogAudioStop() {
111 std::lock_guard<std::recursive_mutex> lock(lock_);
112 audio_stop_time_ms_ = bluetooth::common::time_get_os_boottime_ms();
113 }
LogAudioStopMetricsAndReset()114 void LogAudioStopMetricsAndReset() {
115 std::lock_guard<std::recursive_mutex> lock(lock_);
116 LogAudioStop();
117 StoreMetrics();
118 ResetPreserveSession();
119 }
SetCodecIndex(int64_t codec_index)120 void SetCodecIndex(int64_t codec_index) {
121 std::lock_guard<std::recursive_mutex> lock(lock_);
122 codec_index_ = codec_index;
123 }
124
125 private:
126 std::recursive_mutex lock_;
127 int64_t audio_start_time_ms_ = -1;
128 int64_t audio_stop_time_ms_ = -1;
129 int64_t codec_index_ = -1;
130 };
131
132 static A2dpOffloadAudioStats a2dp_offload_audio_stats;
133
134 class BluetoothAudioHost : public IBluetoothAudioHost {
135 public:
startStream()136 Return<void> startStream() override {
137 btif_a2dp_audio_send_start_req();
138 return Void();
139 }
suspendStream()140 Return<void> suspendStream() override {
141 btif_a2dp_audio_send_suspend_req();
142 return Void();
143 }
stopStream()144 Return<void> stopStream() override {
145 btif_a2dp_audio_send_stop_req();
146 return Void();
147 }
148
149 // TODO : Delay reporting
150 /* Return<void> a2dp_get_sink_latency() {
151 LOG_INFO("%s:start ", __func__);
152 btif_a2dp_audio_send_sink_latency();
153 return Void();
154 }*/
155 };
156
157 class BluetoothAudioDeathRecipient : public hidl_death_recipient {
158 public:
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)159 void serviceDied(
160 uint64_t /*cookie*/,
161 const wp<::android::hidl::base::V1_0::IBase>& /*who*/) override {
162 LOG_ERROR("%s", __func__);
163 // Restart the session on the correct thread
164 do_in_main_thread(FROM_HERE,
165 base::Bind(&btif_a2dp_audio_interface_restart_session));
166 }
167 };
168 sp<BluetoothAudioDeathRecipient> bluetoothAudioDeathRecipient =
169 new BluetoothAudioDeathRecipient();
170
mapToStatus(uint8_t resp)171 static Status mapToStatus(uint8_t resp) {
172 switch (resp) {
173 case A2DP_CTRL_ACK_SUCCESS:
174 return Status::SUCCESS;
175 break;
176 case A2DP_CTRL_ACK_PENDING:
177 return Status::PENDING;
178 break;
179 case A2DP_CTRL_ACK_FAILURE:
180 case A2DP_CTRL_ACK_INCALL_FAILURE:
181 case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
182 return Status::FAILURE;
183 default:
184 APPL_TRACE_WARNING("%s: unknown status recevied :%d", __func__, resp);
185 return Status::FAILURE;
186 break;
187 }
188 }
189
btif_a2dp_get_codec_configuration(CodecConfiguration * p_codec_info)190 static void btif_a2dp_get_codec_configuration(
191 CodecConfiguration* p_codec_info) {
192 LOG_INFO("%s", __func__);
193 tBT_A2DP_OFFLOAD a2dp_offload;
194 A2dpCodecConfig* a2dpCodecConfig = bta_av_get_a2dp_current_codec();
195 a2dpCodecConfig->getCodecSpecificConfig(&a2dp_offload);
196 btav_a2dp_codec_config_t codec_config;
197 codec_config = a2dpCodecConfig->getCodecConfig();
198 a2dp_offload_audio_stats.SetCodecIndex(a2dpCodecConfig->codecIndex());
199 switch (codec_config.codec_type) {
200 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
201 p_codec_info->codecType =
202 (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
203 BTA_AV_CODEC_TYPE_SBC;
204 p_codec_info->codecSpecific.sbcData.codecParameters =
205 a2dp_offload.codec_info[0];
206 LOG_INFO(" %s: codec parameters =%d", __func__,
207 a2dp_offload.codec_info[0]);
208 p_codec_info->codecSpecific.sbcData.minBitpool =
209 a2dp_offload.codec_info[1];
210 p_codec_info->codecSpecific.sbcData.maxBitpool =
211 a2dp_offload.codec_info[2];
212 break;
213 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
214 p_codec_info->codecType =
215 (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
216 BTA_AV_CODEC_TYPE_AAC;
217 break;
218 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
219 p_codec_info->codecType =
220 (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
221 BTA_AV_CODEC_TYPE_APTX;
222 break;
223 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
224 p_codec_info->codecType =
225 (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
226 BTA_AV_CODEC_TYPE_APTXHD;
227 break;
228 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
229 p_codec_info->codecType =
230 (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
231 BTA_AV_CODEC_TYPE_LDAC;
232 p_codec_info->codecSpecific.ldacData.bitrateIndex =
233 a2dp_offload.codec_info[6];
234 break;
235 default:
236 APPL_TRACE_ERROR("%s: Unknown Codec type :%d ", __func__,
237 codec_config.codec_type);
238 }
239
240 // Obtain the MTU
241 RawAddress peer_addr = btif_av_source_active_peer();
242 tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
243 bta_av_co_get_peer_params(peer_addr, &peer_param);
244 int effectiveMtu = a2dpCodecConfig->getEffectiveMtu();
245 if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
246 p_codec_info->peerMtu = effectiveMtu;
247 } else {
248 p_codec_info->peerMtu = peer_param.peer_mtu;
249 }
250 LOG_INFO("%s: peer MTU: %d effective MTU: %d result MTU: %d", __func__,
251 peer_param.peer_mtu, effectiveMtu, p_codec_info->peerMtu);
252
253 p_codec_info->sampleRate =
254 (::android::hardware::bluetooth::a2dp::V1_0::SampleRate)
255 codec_config.sample_rate;
256 p_codec_info->bitsPerSample =
257 (::android::hardware::bluetooth::a2dp::V1_0::BitsPerSample)
258 codec_config.bits_per_sample;
259 p_codec_info->channelMode =
260 (::android::hardware::bluetooth::a2dp::V1_0::ChannelMode)
261 codec_config.channel_mode;
262 p_codec_info->encodedAudioBitrate = a2dpCodecConfig->getTrackBitRate();
263 }
264
btif_a2dp_audio_interface_init()265 static void btif_a2dp_audio_interface_init() {
266 LOG_INFO("%s", __func__);
267
268 btAudio = IBluetoothAudioOffload::getService();
269 CHECK(btAudio != nullptr);
270
271 auto death_link = btAudio->linkToDeath(bluetoothAudioDeathRecipient, 0);
272 if (!death_link.isOk()) {
273 LOG_ERROR("%s: Cannot observe the Bluetooth Audio HAL's death", __func__);
274 }
275
276 LOG_INFO("%s: IBluetoothAudioOffload::getService() returned %p (%s)",
277 __func__, btAudio.get(), (btAudio->isRemote() ? "remote" : "local"));
278
279 LOG_INFO("%s:Init returned", __func__);
280 }
281
btif_a2dp_audio_interface_deinit()282 static void btif_a2dp_audio_interface_deinit() {
283 LOG_INFO("%s: start", __func__);
284 if (btAudio != nullptr) {
285 auto death_unlink = btAudio->unlinkToDeath(bluetoothAudioDeathRecipient);
286 if (!death_unlink.isOk()) {
287 LOG_ERROR("%s: Error unlinking death observer from Bluetooth Audio HAL",
288 __func__);
289 }
290 }
291 btAudio = nullptr;
292 }
293
btif_a2dp_audio_interface_start_session()294 void btif_a2dp_audio_interface_start_session() {
295 LOG_INFO("%s", __func__);
296 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
297 bluetooth::common::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
298 a2dp_offload_audio_stats.Reset();
299 btif_a2dp_audio_interface_init();
300 CHECK(btAudio != nullptr);
301 CodecConfiguration codec_info;
302 btif_a2dp_get_codec_configuration(&codec_info);
303 android::sp<IBluetoothAudioHost> host_if = new BluetoothAudioHost();
304 btAudio->startSession(host_if, codec_info);
305 }
306
btif_a2dp_audio_interface_end_session()307 void btif_a2dp_audio_interface_end_session() {
308 LOG_INFO("%s", __func__);
309 a2dp_offload_audio_stats.LogAudioStopMetricsAndReset();
310 BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
311 bluetooth::common::DISCONNECT_REASON_UNKNOWN, 0);
312 a2dp_offload_audio_stats.Reset();
313 if (btAudio == nullptr) return;
314 auto ret = btAudio->endSession();
315 if (!ret.isOk()) {
316 LOG_ERROR("HAL server is dead");
317 }
318 btif_a2dp_audio_interface_deinit();
319 }
320
321 // Conditionally restart the session only if it was started before
btif_a2dp_audio_interface_restart_session()322 static void btif_a2dp_audio_interface_restart_session() {
323 LOG_INFO("%s", __func__);
324 if (btAudio == nullptr) {
325 LOG_INFO("%s: nothing to restart - session was not started", __func__);
326 return;
327 }
328 btAudio = nullptr;
329 btif_a2dp_audio_interface_start_session();
330 }
331
btif_a2dp_audio_on_started(tBTA_AV_STATUS status)332 void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) {
333 LOG_INFO("%s: status = %d", __func__, status);
334 if (btAudio != nullptr) {
335 if (a2dp_cmd_pending == A2DP_CTRL_CMD_START) {
336 if (status != A2DP_CTRL_ACK_PENDING) {
337 a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
338 }
339 LOG_INFO("%s: calling method onStarted", __func__);
340 auto hal_status = mapToStatus(status);
341 btAudio->streamStarted(hal_status);
342 if (hal_status == Status::SUCCESS) {
343 a2dp_offload_audio_stats.LogAudioStart();
344 }
345 }
346 }
347 }
348
btif_a2dp_audio_on_suspended(tBTA_AV_STATUS status)349 void btif_a2dp_audio_on_suspended(tBTA_AV_STATUS status) {
350 LOG_INFO("%s: status = %d", __func__, status);
351 if (btAudio != nullptr) {
352 if (a2dp_cmd_pending == A2DP_CTRL_CMD_SUSPEND) {
353 if (status != A2DP_CTRL_ACK_PENDING) {
354 a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
355 }
356 LOG_INFO("calling method onSuspended");
357 auto hal_status = mapToStatus(status);
358 btAudio->streamSuspended(hal_status);
359 if (hal_status == Status::SUCCESS) {
360 a2dp_offload_audio_stats.LogAudioStopMetricsAndReset();
361 }
362 }
363 }
364 }
365
btif_a2dp_audio_on_stopped(tBTA_AV_STATUS status)366 void btif_a2dp_audio_on_stopped(tBTA_AV_STATUS status) {
367 LOG_INFO("%s: status = %d", __func__, status);
368 if (btAudio != nullptr && a2dp_cmd_pending == A2DP_CTRL_CMD_START) {
369 a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
370 LOG_INFO("%s: Remote disconnected when start under progress", __func__);
371 btAudio->streamStarted(mapToStatus(A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS));
372 a2dp_offload_audio_stats.LogAudioStopMetricsAndReset();
373 }
374 }
btif_a2dp_audio_send_start_req()375 void btif_a2dp_audio_send_start_req() {
376 LOG_INFO("%s", __func__);
377 uint8_t resp;
378 resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_START);
379 if (btAudio != nullptr) {
380 auto status = mapToStatus(resp);
381 auto ret = btAudio->streamStarted(status);
382 if (status == Status::SUCCESS) {
383 a2dp_offload_audio_stats.LogAudioStart();
384 }
385 if (!ret.isOk()) LOG_ERROR("HAL server died");
386 }
387 }
btif_a2dp_audio_send_suspend_req()388 void btif_a2dp_audio_send_suspend_req() {
389 LOG_INFO("%s", __func__);
390 uint8_t resp;
391 resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_SUSPEND);
392 if (btAudio != nullptr) {
393 auto status = mapToStatus(resp);
394 auto ret = btAudio->streamSuspended(status);
395 if (status == Status::SUCCESS) {
396 a2dp_offload_audio_stats.LogAudioStopMetricsAndReset();
397 }
398 if (!ret.isOk()) LOG_ERROR("HAL server died");
399 }
400 }
401
btif_a2dp_audio_send_stop_req()402 void btif_a2dp_audio_send_stop_req() {
403 LOG_INFO("%s", __func__);
404 btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP);
405 a2dp_offload_audio_stats.LogAudioStopMetricsAndReset();
406 }
407
408 /*void btif_a2dp_audio_send_sink_latency()
409 {
410 LOG_INFO("%s", __func__);
411 uint16_t sink_latency = btif_av_get_sink_latency();
412 if (btAudio != nullptr) {
413 auto ret = btAudio->a2dp_on_get_sink_latency(sink_latency);
414 if (!ret.isOk()) LOG_ERROR("server died");
415 }
416 }*/
417
btif_a2dp_audio_process_request(uint8_t cmd)418 uint8_t btif_a2dp_audio_process_request(uint8_t cmd) {
419 LOG_INFO("%s: cmd: %s", __func__,
420 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd));
421 uint8_t status;
422 switch (cmd) {
423 case A2DP_CTRL_CMD_START:
424 /*
425 * Don't send START request to stack while we are in a call.
426 * Some headsets such as "Sony MW600", don't allow AVDTP START
427 * while in a call, and respond with BAD_STATE.
428 */
429 if (!bluetooth::headset::IsCallIdle()) {
430 APPL_TRACE_WARNING("%s: A2DP command %s failed as call state is busy",
431 __func__,
432 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd));
433 status = A2DP_CTRL_ACK_INCALL_FAILURE;
434 break;
435 }
436 if (btif_av_stream_started_ready()) {
437 /*
438 * Already started, setup audio data channel listener and ACK
439 * back immediately.
440 */
441 status = A2DP_CTRL_ACK_SUCCESS;
442 break;
443 }
444 if (btif_av_stream_ready()) {
445 /*
446 * Post start event and wait for audio path to open.
447 * If we are the source, the ACK will be sent after the start
448 * procedure is completed, othewise send it now.
449 */
450 btif_av_stream_start();
451 if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
452 status = A2DP_CTRL_ACK_SUCCESS;
453 break;
454 }
455 /*Return pending and ack when start stream cfm received from remote*/
456 status = A2DP_CTRL_ACK_PENDING;
457 break;
458 }
459
460 APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready",
461 __func__,
462 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd));
463 status = A2DP_CTRL_ACK_FAILURE;
464 break;
465
466 case A2DP_CTRL_CMD_STOP:
467 if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
468 !btif_a2dp_source_is_streaming()) {
469 /* We are already stopped, just ack back */
470 status = A2DP_CTRL_ACK_SUCCESS;
471 break;
472 }
473 btif_av_stream_stop(RawAddress::kEmpty);
474 status = A2DP_CTRL_ACK_SUCCESS;
475 break;
476
477 case A2DP_CTRL_CMD_SUSPEND:
478 /* Local suspend */
479 if (btif_av_stream_started_ready()) {
480 btif_av_stream_suspend();
481 status = A2DP_CTRL_ACK_PENDING;
482 break;
483 }
484 /* If we are not in started state, just ack back ok and let
485 * audioflinger close the channel. This can happen if we are
486 * remotely suspended, clear REMOTE SUSPEND flag.
487 */
488 btif_av_clear_remote_suspend_flag();
489 status = A2DP_CTRL_ACK_SUCCESS;
490 break;
491
492 case A2DP_CTRL_CMD_OFFLOAD_START:
493 btif_av_stream_start_offload();
494 status = A2DP_CTRL_ACK_PENDING;
495 break;
496
497 default:
498 APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
499 status = A2DP_CTRL_ACK_FAILURE;
500 break;
501 }
502 LOG_INFO("a2dp-ctrl-cmd : %s DONE returning status %d",
503 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd), status);
504 if (status == A2DP_CTRL_ACK_PENDING) {
505 a2dp_cmd_pending = cmd;
506 } else {
507 a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
508 }
509 return status;
510 }
511