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 #include <a2dp_vendor.h> 23 #include <a2dp_vendor_ldac_constants.h> 24 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioHost.h> 25 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioOffload.h> 26 #include <android/hardware/bluetooth/a2dp/1.0/types.h> 27 #include <base/logging.h> 28 #include <hwbinder/ProcessState.h> 29 #include <utils/RefBase.h> 30 #include "a2dp_sbc.h" 31 #include "bt_common.h" 32 #include "bta/av/bta_av_int.h" 33 #include "btif_a2dp.h" 34 #include "btif_a2dp_control.h" 35 #include "btif_a2dp_sink.h" 36 #include "btif_a2dp_source.h" 37 #include "btif_av.h" 38 #include "btif_av_co.h" 39 #include "btif_hf.h" 40 #include "osi/include/osi.h" 41 42 using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload; 43 using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost; 44 using android::hardware::bluetooth::a2dp::V1_0::Status; 45 using android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration; 46 using android::hardware::bluetooth::a2dp::V1_0::CodecType; 47 using android::hardware::bluetooth::a2dp::V1_0::SampleRate; 48 using android::hardware::bluetooth::a2dp::V1_0::BitsPerSample; 49 using android::hardware::bluetooth::a2dp::V1_0::ChannelMode; 50 using android::hardware::ProcessState; 51 using ::android::hardware::Return; 52 using ::android::hardware::Void; 53 using ::android::hardware::hidl_vec; 54 using ::android::sp; 55 android::sp<IBluetoothAudioOffload> btAudio; 56 57 #define CASE_RETURN_STR(const) \ 58 case const: \ 59 return #const; 60 static uint8_t a2dp_cmd_pending = A2DP_CTRL_CMD_NONE; 61 static Status mapToStatus(uint8_t resp); 62 uint8_t btif_a2dp_audio_process_request(uint8_t cmd); 63 64 static void btif_a2dp_audio_send_start_req(); 65 static void btif_a2dp_audio_send_suspend_req(); 66 static void btif_a2dp_audio_interface_init(); 67 static void btif_a2dp_audio_interface_deinit(); 68 // Delay reporting 69 // static void btif_a2dp_audio_send_sink_latency(); 70 71 class BluetoothAudioHost : public IBluetoothAudioHost { 72 public: 73 Return<void> startStream() { 74 btif_a2dp_audio_send_start_req(); 75 return Void(); 76 } 77 Return<void> suspendStream() { 78 btif_a2dp_audio_send_suspend_req(); 79 return Void(); 80 } 81 Return<void> stopStream() { 82 btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP); 83 return Void(); 84 } 85 86 // TODO : Delay reporting 87 /* Return<void> a2dp_get_sink_latency() { 88 LOG_INFO(LOG_TAG,"%s:start ", __func__); 89 btif_a2dp_audio_send_sink_latency(); 90 return Void(); 91 }*/ 92 }; 93 94 static Status mapToStatus(uint8_t resp) { 95 switch (resp) { 96 case A2DP_CTRL_ACK_SUCCESS: 97 return Status::SUCCESS; 98 break; 99 case A2DP_CTRL_ACK_PENDING: 100 return Status::PENDING; 101 break; 102 case A2DP_CTRL_ACK_FAILURE: 103 case A2DP_CTRL_ACK_INCALL_FAILURE: 104 case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS: 105 return Status::FAILURE; 106 default: 107 APPL_TRACE_WARNING("%s: unknown status recevied :%d", __func__, resp); 108 return Status::FAILURE; 109 break; 110 } 111 } 112 113 static void btif_a2dp_get_codec_configuration( 114 CodecConfiguration* p_codec_info) { 115 LOG_INFO(LOG_TAG, "%s", __func__); 116 tBT_A2DP_OFFLOAD a2dp_offload; 117 A2dpCodecConfig* a2dpCodecConfig = bta_av_get_a2dp_current_codec(); 118 a2dpCodecConfig->getCodecSpecificConfig(&a2dp_offload); 119 btav_a2dp_codec_config_t codec_config; 120 codec_config = a2dpCodecConfig->getCodecConfig(); 121 switch (codec_config.codec_type) { 122 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: 123 p_codec_info->codecType = 124 (::android::hardware::bluetooth::a2dp::V1_0::CodecType) 125 BTA_AV_CODEC_TYPE_SBC; 126 p_codec_info->codecSpecific.sbcData.codecParameters = 127 a2dp_offload.codec_info[0]; 128 LOG_INFO(LOG_TAG, " %s: codec parameters =%d", __func__, 129 a2dp_offload.codec_info[0]); 130 p_codec_info->codecSpecific.sbcData.minBitpool = 131 a2dp_offload.codec_info[1]; 132 p_codec_info->codecSpecific.sbcData.maxBitpool = 133 a2dp_offload.codec_info[2]; 134 break; 135 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC: 136 p_codec_info->codecType = 137 (::android::hardware::bluetooth::a2dp::V1_0::CodecType) 138 BTA_AV_CODEC_TYPE_AAC; 139 break; 140 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX: 141 p_codec_info->codecType = 142 (::android::hardware::bluetooth::a2dp::V1_0::CodecType) 143 BTA_AV_CODEC_TYPE_APTX; 144 break; 145 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: 146 p_codec_info->codecType = 147 (::android::hardware::bluetooth::a2dp::V1_0::CodecType) 148 BTA_AV_CODEC_TYPE_APTXHD; 149 break; 150 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: 151 p_codec_info->codecType = 152 (::android::hardware::bluetooth::a2dp::V1_0::CodecType) 153 BTA_AV_CODEC_TYPE_LDAC; 154 p_codec_info->codecSpecific.ldacData.bitrateIndex = 155 a2dp_offload.codec_info[6]; 156 break; 157 default: 158 APPL_TRACE_ERROR("%s: Unknown Codec type :%d ", __func__, 159 codec_config.codec_type); 160 } 161 162 // Obtain the MTU 163 RawAddress peer_addr = btif_av_source_active_peer(); 164 tA2DP_ENCODER_INIT_PEER_PARAMS peer_param; 165 bta_av_co_get_peer_params(peer_addr, &peer_param); 166 int effectiveMtu = a2dpCodecConfig->getEffectiveMtu(); 167 if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) { 168 p_codec_info->peerMtu = effectiveMtu; 169 } else { 170 p_codec_info->peerMtu = peer_param.peer_mtu; 171 } 172 LOG_INFO(LOG_TAG, "%s: peer MTU: %d effective MTU: %d result MTU: %d", 173 __func__, peer_param.peer_mtu, effectiveMtu, p_codec_info->peerMtu); 174 175 p_codec_info->sampleRate = 176 (::android::hardware::bluetooth::a2dp::V1_0::SampleRate) 177 codec_config.sample_rate; 178 p_codec_info->bitsPerSample = 179 (::android::hardware::bluetooth::a2dp::V1_0::BitsPerSample) 180 codec_config.bits_per_sample; 181 p_codec_info->channelMode = 182 (::android::hardware::bluetooth::a2dp::V1_0::ChannelMode) 183 codec_config.channel_mode; 184 p_codec_info->encodedAudioBitrate = a2dpCodecConfig->getTrackBitRate(); 185 } 186 187 static void btif_a2dp_audio_interface_init() { 188 LOG_INFO(LOG_TAG, "%s", __func__); 189 190 btAudio = IBluetoothAudioOffload::getService(); 191 CHECK(btAudio != nullptr); 192 193 LOG_DEBUG( 194 LOG_TAG, "%s: IBluetoothAudioOffload::getService() returned %p (%s)", 195 __func__, btAudio.get(), (btAudio->isRemote() ? "remote" : "local")); 196 197 LOG_INFO(LOG_TAG, "%s:Init returned", __func__); 198 } 199 200 static void btif_a2dp_audio_interface_deinit() { 201 LOG_INFO(LOG_TAG, "%s: start", __func__); 202 btAudio = nullptr; 203 } 204 205 void btif_a2dp_audio_interface_start_session() { 206 LOG_INFO(LOG_TAG, "%s", __func__); 207 btif_a2dp_audio_interface_init(); 208 CHECK(btAudio != nullptr); 209 CodecConfiguration codec_info; 210 btif_a2dp_get_codec_configuration(&codec_info); 211 android::sp<IBluetoothAudioHost> host_if = new BluetoothAudioHost(); 212 btAudio->startSession(host_if, codec_info); 213 } 214 215 void btif_a2dp_audio_interface_end_session() { 216 LOG_INFO(LOG_TAG, "%s", __func__); 217 if (btAudio == nullptr) return; 218 auto ret = btAudio->endSession(); 219 if (!ret.isOk()) { 220 LOG_ERROR(LOG_TAG, "HAL server is dead"); 221 } 222 btif_a2dp_audio_interface_deinit(); 223 } 224 225 void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) { 226 LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status); 227 if (btAudio != nullptr) { 228 if (a2dp_cmd_pending == A2DP_CTRL_CMD_START) { 229 LOG_INFO(LOG_TAG, "%s: calling method onStarted", __func__); 230 btAudio->streamStarted(mapToStatus(status)); 231 } 232 } 233 } 234 235 void btif_a2dp_audio_on_suspended(tBTA_AV_STATUS status) { 236 LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status); 237 if (btAudio != nullptr) { 238 if (a2dp_cmd_pending == A2DP_CTRL_CMD_SUSPEND) { 239 LOG_INFO(LOG_TAG, "calling method onSuspended"); 240 btAudio->streamSuspended(mapToStatus(status)); 241 } 242 } 243 } 244 245 void btif_a2dp_audio_on_stopped(tBTA_AV_STATUS status) { 246 LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status); 247 if (btAudio != nullptr && a2dp_cmd_pending == A2DP_CTRL_CMD_START) { 248 LOG_INFO(LOG_TAG, "%s: Remote disconnected when start under progress", 249 __func__); 250 btAudio->streamStarted(mapToStatus(A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS)); 251 } 252 } 253 void btif_a2dp_audio_send_start_req() { 254 LOG_INFO(LOG_TAG, "%s", __func__); 255 uint8_t resp; 256 resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_START); 257 if (btAudio != nullptr) { 258 auto ret = btAudio->streamStarted(mapToStatus(resp)); 259 if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died"); 260 } 261 } 262 void btif_a2dp_audio_send_suspend_req() { 263 LOG_INFO(LOG_TAG, "%s", __func__); 264 uint8_t resp; 265 resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_SUSPEND); 266 if (btAudio != nullptr) { 267 auto ret = btAudio->streamSuspended(mapToStatus(resp)); 268 if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died"); 269 } 270 } 271 /*void btif_a2dp_audio_send_sink_latency() 272 { 273 LOG_INFO(LOG_TAG, "%s", __func__); 274 uint16_t sink_latency = btif_av_get_sink_latency(); 275 if (btAudio != nullptr) { 276 auto ret = btAudio->a2dp_on_get_sink_latency(sink_latency); 277 if (!ret.isOk()) LOG_ERROR(LOG_TAG, "server died"); 278 } 279 }*/ 280 281 uint8_t btif_a2dp_audio_process_request(uint8_t cmd) { 282 LOG_INFO(LOG_TAG, "%s: cmd: %s", __func__, 283 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd)); 284 a2dp_cmd_pending = cmd; 285 uint8_t status; 286 switch (cmd) { 287 case A2DP_CTRL_CMD_START: 288 /* 289 * Don't send START request to stack while we are in a call. 290 * Some headsets such as "Sony MW600", don't allow AVDTP START 291 * while in a call, and respond with BAD_STATE. 292 */ 293 if (!bluetooth::headset::IsCallIdle()) { 294 APPL_TRACE_WARNING("%s: A2DP command %s failed as call state is busy", 295 __func__, 296 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd)); 297 status = A2DP_CTRL_ACK_INCALL_FAILURE; 298 break; 299 } 300 if (btif_av_stream_started_ready()) { 301 /* 302 * Already started, setup audio data channel listener and ACK 303 * back immediately. 304 */ 305 status = A2DP_CTRL_ACK_SUCCESS; 306 break; 307 } 308 if (btif_av_stream_ready()) { 309 /* 310 * Post start event and wait for audio path to open. 311 * If we are the source, the ACK will be sent after the start 312 * procedure is completed, othewise send it now. 313 */ 314 btif_av_stream_start(); 315 if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) { 316 status = A2DP_CTRL_ACK_SUCCESS; 317 break; 318 } 319 /*Return pending and ack when start stream cfm received from remote*/ 320 status = A2DP_CTRL_ACK_PENDING; 321 break; 322 } 323 324 APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready", 325 __func__, 326 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd)); 327 return A2DP_CTRL_ACK_FAILURE; 328 break; 329 330 case A2DP_CTRL_CMD_STOP: 331 if (btif_av_get_peer_sep() == AVDT_TSEP_SNK && 332 !btif_a2dp_source_is_streaming()) { 333 /* We are already stopped, just ack back */ 334 status = A2DP_CTRL_ACK_SUCCESS; 335 break; 336 } 337 btif_av_stream_stop(RawAddress::kEmpty); 338 return A2DP_CTRL_ACK_SUCCESS; 339 break; 340 341 case A2DP_CTRL_CMD_SUSPEND: 342 /* Local suspend */ 343 if (btif_av_stream_started_ready()) { 344 btif_av_stream_suspend(); 345 status = A2DP_CTRL_ACK_PENDING; 346 break; 347 } 348 /* If we are not in started state, just ack back ok and let 349 * audioflinger close the channel. This can happen if we are 350 * remotely suspended, clear REMOTE SUSPEND flag. 351 */ 352 btif_av_clear_remote_suspend_flag(); 353 status = A2DP_CTRL_ACK_SUCCESS; 354 break; 355 356 case A2DP_CTRL_CMD_OFFLOAD_START: 357 btif_av_stream_start_offload(); 358 status = A2DP_CTRL_ACK_PENDING; 359 break; 360 361 default: 362 APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd); 363 status = A2DP_CTRL_ACK_FAILURE; 364 break; 365 } 366 LOG_INFO(LOG_TAG, "a2dp-ctrl-cmd : %s DONE returning status %d", 367 audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd), status); 368 return status; 369 } 370