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