blob: 1b362e594339fab3751e744a2089ab61ae2219ad [file] [log] [blame]
Cheney Niad05f3e2018-11-08 16:41:02 +08001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Hansong Zhangb3ffbed2019-02-15 16:19:44 -080017#include "a2dp_encoding.h"
Cheney Niad05f3e2018-11-08 16:41:02 +080018#include "client_interface.h"
19
Satish kumar sugasicf284d22019-04-25 19:55:31 -070020#include "a2dp_aac_constants.h"
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -080021#include "a2dp_sbc_constants.h"
22#include "a2dp_vendor_ldac_constants.h"
23#include "bta/av/bta_av_int.h"
Cheney Niad05f3e2018-11-08 16:41:02 +080024#include "btif_a2dp_source.h"
25#include "btif_av.h"
26#include "btif_av_co.h"
27#include "btif_hf.h"
28#include "osi/include/properties.h"
29
30namespace {
31
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -080032using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
33using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
Cheney Niad05f3e2018-11-08 16:41:02 +080034using ::android::hardware::bluetooth::audio::V2_0::CodecType;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -080035using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
36using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
37using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
38using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
39using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
40using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
Cheney Niad05f3e2018-11-08 16:41:02 +080041using ::bluetooth::audio::AudioConfiguration;
42using ::bluetooth::audio::BitsPerSample;
43using ::bluetooth::audio::BluetoothAudioCtrlAck;
44using ::bluetooth::audio::ChannelMode;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -080045using ::bluetooth::audio::CodecConfiguration;
Cheney Niad05f3e2018-11-08 16:41:02 +080046using ::bluetooth::audio::PcmParameters;
47using ::bluetooth::audio::SampleRate;
48using ::bluetooth::audio::SessionType;
49
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -080050const CodecConfiguration kInvalidCodecConfiguration = {
51 .codecType = CodecType::UNKNOWN,
52 .encodedAudioBitrate = 0x00000000,
53 .peerMtu = 0xffff,
54 .isScmstEnabled = false,
55 .config = {}};
56
Cheney Niad05f3e2018-11-08 16:41:02 +080057BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack);
Cheney Niad05f3e2018-11-08 16:41:02 +080058
59// Provide call-in APIs for the Bluetooth Audio HAL
60class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance {
61 public:
Cheney Ni8552e952019-02-21 19:54:10 +080062 A2dpTransport(SessionType sessionType)
63 : IBluetoothTransportInstance(sessionType, {}),
Cheney Niad05f3e2018-11-08 16:41:02 +080064 a2dp_pending_cmd_(A2DP_CTRL_CMD_NONE),
65 remote_delay_report_(0),
66 total_bytes_read_(0),
67 data_position_({}){};
68
69 BluetoothAudioCtrlAck StartRequest() override {
70 // Check if a previous request is not finished
71 if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
72 LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
73 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
74 } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
75 LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
76 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
77 }
78
79 // Don't send START request to stack while we are in a call
80 if (!bluetooth::headset::IsCallIdle()) {
81 LOG(ERROR) << __func__ << ": call state is busy";
82 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE);
83 }
84
Cheney Ni8e9ecc72019-11-21 02:49:12 +080085 if (btif_av_stream_started_ready()) {
86 // Already started, ACK back immediately.
87 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
Cheney Niad05f3e2018-11-08 16:41:02 +080088 }
Cheney Niad05f3e2018-11-08 16:41:02 +080089 if (btif_av_stream_ready()) {
90 /*
91 * Post start event and wait for audio path to open.
92 * If we are the source, the ACK will be sent after the start
93 * procedure is completed, othewise send it now.
94 */
95 a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
96 btif_av_stream_start();
97 if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
98 LOG(INFO) << __func__ << ": accepted";
99 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
100 }
101 a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
102 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
103 }
Cheney Niad05f3e2018-11-08 16:41:02 +0800104 LOG(ERROR) << __func__ << ": AV stream is not ready to start";
105 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
106 }
107
108 BluetoothAudioCtrlAck SuspendRequest() override {
109 // Previous request is not finished
110 if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
111 LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_SUSPEND in progress";
112 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
113 } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
114 LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
115 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
116 }
117 // Local suspend
118 if (btif_av_stream_started_ready()) {
119 LOG(INFO) << __func__ << ": accepted";
120 a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
121 btif_av_stream_suspend();
122 return BluetoothAudioCtrlAck::PENDING;
123 }
124 /* If we are not in started state, just ack back ok and let
125 * audioflinger close the channel. This can happen if we are
126 * remotely suspended, clear REMOTE SUSPEND flag.
127 */
128 btif_av_clear_remote_suspend_flag();
129 return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
130 }
131
132 void StopRequest() override {
133 if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
Cheney Ni8e9ecc72019-11-21 02:49:12 +0800134 !btif_av_stream_started_ready()) {
Cheney Niad05f3e2018-11-08 16:41:02 +0800135 return;
136 }
137 LOG(INFO) << __func__ << ": handling";
138 a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
139 btif_av_stream_stop(RawAddress::kEmpty);
140 }
141
142 bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
143 uint64_t* total_bytes_read,
144 timespec* data_position) override {
145 *remote_delay_report_ns = remote_delay_report_ * 100000u;
146 *total_bytes_read = total_bytes_read_;
147 *data_position = data_position_;
148 VLOG(2) << __func__ << ": delay=" << remote_delay_report_
149 << "/10ms, data=" << total_bytes_read_
150 << " byte(s), timestamp=" << data_position_.tv_sec << "."
151 << data_position_.tv_nsec << "s";
152 return true;
153 }
154
155 void MetadataChanged(const source_metadata_t& source_metadata) override {
156 auto track_count = source_metadata.track_count;
157 auto tracks = source_metadata.tracks;
158 VLOG(1) << __func__ << ": " << track_count << " track(s) received";
159 while (track_count) {
160 VLOG(2) << __func__ << ": usage=" << tracks->usage
161 << ", content_type=" << tracks->content_type
162 << ", gain=" << tracks->gain;
163 --track_count;
164 ++tracks;
165 }
166 }
167
168 tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
169
170 void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
171
172 void ResetPresentationPosition() override {
173 remote_delay_report_ = 0;
174 total_bytes_read_ = 0;
175 data_position_ = {};
176 }
177
178 void LogBytesRead(size_t bytes_read) override {
179 if (bytes_read != 0) {
180 total_bytes_read_ += bytes_read;
181 clock_gettime(CLOCK_MONOTONIC, &data_position_);
182 }
183 }
184
185 // delay reports from AVDTP is based on 1/10 ms (100us)
186 void SetRemoteDelay(uint16_t delay_report) {
187 remote_delay_report_ = delay_report;
188 }
189
190 private:
191 tA2DP_CTRL_CMD a2dp_pending_cmd_;
192 uint16_t remote_delay_report_;
193 uint64_t total_bytes_read_;
194 timespec data_position_;
195};
196
197A2dpTransport* a2dp_sink = nullptr;
198
199// Common interface to call-out into Bluetooth Audio HAL
200bluetooth::audio::BluetoothAudioClientInterface* a2dp_hal_clientif = nullptr;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800201auto session_type = SessionType::UNKNOWN;
Cheney Niad05f3e2018-11-08 16:41:02 +0800202
203// Save the value if the remote reports its delay before a2dp_sink is
204// initialized
205uint16_t remote_delay = 0;
206
Cheney Ni3abcc012019-03-14 20:58:59 +0800207bool btaudio_a2dp_disabled = false;
Cheney Niad05f3e2018-11-08 16:41:02 +0800208bool is_configured = false;
209
210BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
211 switch (ack) {
212 case A2DP_CTRL_ACK_SUCCESS:
213 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
214 case A2DP_CTRL_ACK_PENDING:
215 return BluetoothAudioCtrlAck::PENDING;
216 case A2DP_CTRL_ACK_INCALL_FAILURE:
217 return BluetoothAudioCtrlAck::FAILURE_BUSY;
218 case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
219 return BluetoothAudioCtrlAck::FAILURE_DISCONNECTING;
220 case A2DP_CTRL_ACK_UNSUPPORTED: /* Offloading but resource failure */
221 return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
222 case A2DP_CTRL_ACK_FAILURE:
223 return BluetoothAudioCtrlAck::FAILURE;
224 default:
225 return BluetoothAudioCtrlAck::FAILURE;
226 }
227}
228
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800229SampleRate a2dp_codec_to_hal_sample_rate(
230 const btav_a2dp_codec_config_t& a2dp_codec_config) {
231 switch (a2dp_codec_config.sample_rate) {
232 case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
233 return SampleRate::RATE_44100;
234 case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
235 return SampleRate::RATE_48000;
236 case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
237 return SampleRate::RATE_88200;
238 case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
239 return SampleRate::RATE_96000;
240 case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
241 return SampleRate::RATE_176400;
242 case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
243 return SampleRate::RATE_192000;
244 case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
245 return SampleRate::RATE_16000;
246 case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
247 return SampleRate::RATE_24000;
248 default:
249 return SampleRate::RATE_UNKNOWN;
250 }
251}
252
253BitsPerSample a2dp_codec_to_hal_bits_per_sample(
254 const btav_a2dp_codec_config_t& a2dp_codec_config) {
255 switch (a2dp_codec_config.bits_per_sample) {
256 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
257 return BitsPerSample::BITS_16;
258 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
259 return BitsPerSample::BITS_24;
260 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
261 return BitsPerSample::BITS_32;
262 default:
263 return BitsPerSample::BITS_UNKNOWN;
264 }
265}
266
267ChannelMode a2dp_codec_to_hal_channel_mode(
268 const btav_a2dp_codec_config_t& a2dp_codec_config) {
269 switch (a2dp_codec_config.channel_mode) {
270 case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
271 return ChannelMode::MONO;
272 case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
273 return ChannelMode::STEREO;
274 default:
275 return ChannelMode::UNKNOWN;
276 }
277}
278
279bool a2dp_get_selected_hal_codec_config(CodecConfiguration* codec_config) {
280 A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
281 if (a2dp_codec_configs == nullptr) {
282 LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
283 *codec_config = kInvalidCodecConfiguration;
284 return false;
285 }
286 btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
287 tBT_A2DP_OFFLOAD a2dp_offload;
288 a2dp_codec_configs->getCodecSpecificConfig(&a2dp_offload);
289 switch (current_codec.codec_type) {
290 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
291 [[fallthrough]];
292 case BTAV_A2DP_CODEC_INDEX_SINK_SBC: {
293 codec_config->codecType = CodecType::SBC;
294 codec_config->config.sbcConfig({});
295 auto sbc_config = codec_config->config.sbcConfig();
296 sbc_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
297 if (sbc_config.sampleRate == SampleRate::RATE_UNKNOWN) {
298 LOG(ERROR) << __func__
299 << ": Unknown SBC sample_rate=" << current_codec.sample_rate;
300 return false;
301 }
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700302 uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800303 switch (channel_mode) {
304 case A2DP_SBC_IE_CH_MD_JOINT:
305 sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
306 break;
307 case A2DP_SBC_IE_CH_MD_STEREO:
308 sbc_config.channelMode = SbcChannelMode::STEREO;
309 break;
310 case A2DP_SBC_IE_CH_MD_DUAL:
311 sbc_config.channelMode = SbcChannelMode::DUAL;
312 break;
313 case A2DP_SBC_IE_CH_MD_MONO:
314 sbc_config.channelMode = SbcChannelMode::MONO;
315 break;
316 default:
317 LOG(ERROR) << __func__
318 << ": Unknown SBC channel_mode=" << channel_mode;
319 sbc_config.channelMode = SbcChannelMode::UNKNOWN;
320 return false;
321 }
322 uint8_t block_length =
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700323 a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800324 switch (block_length) {
325 case A2DP_SBC_IE_BLOCKS_4:
326 sbc_config.blockLength = SbcBlockLength::BLOCKS_4;
327 break;
328 case A2DP_SBC_IE_BLOCKS_8:
329 sbc_config.blockLength = SbcBlockLength::BLOCKS_8;
330 break;
331 case A2DP_SBC_IE_BLOCKS_12:
332 sbc_config.blockLength = SbcBlockLength::BLOCKS_12;
333 break;
334 case A2DP_SBC_IE_BLOCKS_16:
335 sbc_config.blockLength = SbcBlockLength::BLOCKS_16;
336 break;
337 default:
338 LOG(ERROR) << __func__
339 << ": Unknown SBC block_length=" << block_length;
340 return false;
341 }
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700342 uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800343 switch (sub_bands) {
344 case A2DP_SBC_IE_SUBBAND_4:
345 sbc_config.numSubbands = SbcNumSubbands::SUBBAND_4;
346 break;
347 case A2DP_SBC_IE_SUBBAND_8:
348 sbc_config.numSubbands = SbcNumSubbands::SUBBAND_8;
349 break;
350 default:
351 LOG(ERROR) << __func__ << ": Unknown SBC Subbands=" << sub_bands;
352 return false;
353 }
354 uint8_t alloc_method =
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700355 a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800356 switch (alloc_method) {
357 case A2DP_SBC_IE_ALLOC_MD_S:
358 sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
359 break;
360 case A2DP_SBC_IE_ALLOC_MD_L:
361 sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
362 break;
363 default:
364 LOG(ERROR) << __func__
365 << ": Unknown SBC alloc_method=" << alloc_method;
366 return false;
367 }
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700368 sbc_config.minBitpool = a2dp_offload.codec_info[1];
369 sbc_config.maxBitpool = a2dp_offload.codec_info[2];
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800370 sbc_config.bitsPerSample =
371 a2dp_codec_to_hal_bits_per_sample(current_codec);
372 if (sbc_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
373 LOG(ERROR) << __func__ << ": Unknown SBC bits_per_sample="
374 << current_codec.bits_per_sample;
375 return false;
376 }
377 codec_config->config.sbcConfig(sbc_config);
378 break;
379 }
380 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
381 [[fallthrough]];
382 case BTAV_A2DP_CODEC_INDEX_SINK_AAC: {
383 codec_config->codecType = CodecType::AAC;
384 codec_config->config.aacConfig({});
385 auto aac_config = codec_config->config.aacConfig();
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700386 uint8_t object_type = a2dp_offload.codec_info[0];
387 switch (object_type) {
388 case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
389 aac_config.objectType = AacObjectType::MPEG2_LC;
390 break;
391 case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
392 aac_config.objectType = AacObjectType::MPEG4_LC;
393 break;
394 case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
395 aac_config.objectType = AacObjectType::MPEG4_LTP;
396 break;
397 case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
398 aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
399 break;
400 default:
401 LOG(ERROR) << __func__
402 << ": Unknown AAC object_type=" << +object_type;
403 return false;
404 }
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800405 aac_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
406 if (aac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
407 LOG(ERROR) << __func__
408 << ": Unknown AAC sample_rate=" << current_codec.sample_rate;
409 return false;
410 }
411 aac_config.channelMode = a2dp_codec_to_hal_channel_mode(current_codec);
412 if (aac_config.channelMode == ChannelMode::UNKNOWN) {
413 LOG(ERROR) << __func__ << ": Unknown AAC channel_mode="
414 << current_codec.channel_mode;
415 return false;
416 }
Satish kumar sugasicf284d22019-04-25 19:55:31 -0700417 uint8_t vbr_enabled =
418 a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
419 switch (vbr_enabled) {
420 case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
421 aac_config.variableBitRateEnabled = AacVariableBitRate::ENABLED;
422 break;
423 case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
424 aac_config.variableBitRateEnabled = AacVariableBitRate::DISABLED;
425 break;
426 default:
427 LOG(ERROR) << __func__ << ": Unknown AAC VBR=" << +vbr_enabled;
428 return false;
429 }
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800430 aac_config.bitsPerSample =
431 a2dp_codec_to_hal_bits_per_sample(current_codec);
432 if (aac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
433 LOG(ERROR) << __func__ << ": Unknown AAC bits_per_sample="
434 << current_codec.bits_per_sample;
435 return false;
436 }
437 codec_config->config.aacConfig(aac_config);
438 break;
439 }
440 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
441 [[fallthrough]];
442 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: {
443 if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
444 codec_config->codecType = CodecType::APTX;
445 } else {
446 codec_config->codecType = CodecType::APTX_HD;
447 }
448 codec_config->config.aptxConfig({});
449 auto aptx_config = codec_config->config.aptxConfig();
450 aptx_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
451 if (aptx_config.sampleRate == SampleRate::RATE_UNKNOWN) {
452 LOG(ERROR) << __func__ << ": Unknown aptX sample_rate="
453 << current_codec.sample_rate;
454 return false;
455 }
456 aptx_config.channelMode = a2dp_codec_to_hal_channel_mode(current_codec);
457 if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
458 LOG(ERROR) << __func__ << ": Unknown aptX channel_mode="
459 << current_codec.channel_mode;
460 return false;
461 }
462 aptx_config.bitsPerSample =
463 a2dp_codec_to_hal_bits_per_sample(current_codec);
464 if (aptx_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
465 LOG(ERROR) << __func__ << ": Unknown aptX bits_per_sample="
466 << current_codec.bits_per_sample;
467 return false;
468 }
469 codec_config->config.aptxConfig(aptx_config);
470 break;
471 }
472 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: {
473 codec_config->codecType = CodecType::LDAC;
474 codec_config->config.ldacConfig({});
475 auto ldac_config = codec_config->config.ldacConfig();
476 ldac_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
477 if (ldac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
478 LOG(ERROR) << __func__ << ": Unknown LDAC sample_rate="
479 << current_codec.sample_rate;
480 return false;
481 }
482 switch (a2dp_offload.codec_info[7]) {
483 case A2DP_LDAC_CHANNEL_MODE_STEREO:
484 ldac_config.channelMode = LdacChannelMode::STEREO;
485 break;
486 case A2DP_LDAC_CHANNEL_MODE_DUAL:
487 ldac_config.channelMode = LdacChannelMode::DUAL;
488 break;
489 case A2DP_LDAC_CHANNEL_MODE_MONO:
490 ldac_config.channelMode = LdacChannelMode::MONO;
491 break;
492 default:
493 LOG(ERROR) << __func__ << ": Unknown LDAC channel_mode="
494 << a2dp_offload.codec_info[7];
495 ldac_config.channelMode = LdacChannelMode::UNKNOWN;
496 return false;
497 }
498 switch (a2dp_offload.codec_info[6]) {
499 case A2DP_LDAC_QUALITY_HIGH:
500 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_HIGH;
501 break;
502 case A2DP_LDAC_QUALITY_MID:
503 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_MID;
504 break;
505 case A2DP_LDAC_QUALITY_LOW:
506 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_LOW;
507 break;
508 case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
509 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_ABR;
510 break;
511 default:
512 LOG(ERROR) << __func__ << ": Unknown LDAC QualityIndex="
513 << a2dp_offload.codec_info[6];
514 return false;
515 }
516 ldac_config.bitsPerSample =
517 a2dp_codec_to_hal_bits_per_sample(current_codec);
518 if (ldac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
519 LOG(ERROR) << __func__ << ": Unknown LDAC bits_per_sample="
520 << current_codec.bits_per_sample;
521 return false;
522 }
523 codec_config->config.ldacConfig(ldac_config);
524 break;
525 }
526 case BTAV_A2DP_CODEC_INDEX_MAX:
527 [[fallthrough]];
528 default:
529 LOG(ERROR) << __func__
530 << ": Unknown codec_type=" << current_codec.codec_type;
531 codec_config->codecType = CodecType::UNKNOWN;
532 codec_config->config = {};
533 return false;
534 }
535 codec_config->encodedAudioBitrate = a2dp_codec_configs->getTrackBitRate();
536 // Obtain the MTU
537 RawAddress peer_addr = btif_av_source_active_peer();
538 tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
539 bta_av_co_get_peer_params(peer_addr, &peer_param);
540 int effectiveMtu = a2dp_codec_configs->getEffectiveMtu();
541 if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
542 codec_config->peerMtu = effectiveMtu;
543 } else {
544 codec_config->peerMtu = peer_param.peer_mtu;
545 }
546 LOG(INFO) << __func__ << ": CodecConfiguration=" << toString(*codec_config);
547 return true;
548}
549
Cheney Niad05f3e2018-11-08 16:41:02 +0800550bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
551 if (pcm_config == nullptr) return false;
552 A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
553 if (a2dp_codec_configs == nullptr) {
554 LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
555 *pcm_config = ::bluetooth::audio::BluetoothAudioClientInterface::
556 kInvalidPcmConfiguration;
557 return false;
558 }
559
Cheney Niad05f3e2018-11-08 16:41:02 +0800560 btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800561 pcm_config->sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
562 pcm_config->bitsPerSample = a2dp_codec_to_hal_bits_per_sample(current_codec);
563 pcm_config->channelMode = a2dp_codec_to_hal_channel_mode(current_codec);
Cheney Niad05f3e2018-11-08 16:41:02 +0800564 return (pcm_config->sampleRate != SampleRate::RATE_UNKNOWN &&
565 pcm_config->bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
566 pcm_config->channelMode != ChannelMode::UNKNOWN);
567}
568
Cheney Ni3abcc012019-03-14 20:58:59 +0800569// Checking if new bluetooth_audio is supported
570bool is_hal_2_0_force_disabled() {
571 if (!is_configured) {
572 btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
573 is_configured = true;
574 }
575 return btaudio_a2dp_disabled;
576}
577
Cheney Niad05f3e2018-11-08 16:41:02 +0800578} // namespace
579
580namespace bluetooth {
581namespace audio {
582namespace a2dp {
583
Cheney Niad05f3e2018-11-08 16:41:02 +0800584// Checking if new bluetooth_audio is enabled
585bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; }
586
587// Initialize BluetoothAudio HAL: openProvider
588bool init(bluetooth::common::MessageLoopThread* message_loop) {
589 LOG(INFO) << __func__;
590
Cheney Ni3abcc012019-03-14 20:58:59 +0800591 if (is_hal_2_0_force_disabled()) {
592 LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
Cheney Niad05f3e2018-11-08 16:41:02 +0800593 return false;
594 }
595
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800596 if (btif_av_is_a2dp_offload_enabled()) {
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800597 session_type = SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
598 } else {
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800599 session_type = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
600 }
Cheney Ni8552e952019-02-21 19:54:10 +0800601 a2dp_sink = new A2dpTransport(session_type);
Cheney Niad05f3e2018-11-08 16:41:02 +0800602 a2dp_hal_clientif = new bluetooth::audio::BluetoothAudioClientInterface(
603 a2dp_sink, message_loop);
Cheney Ni3abcc012019-03-14 20:58:59 +0800604 if (!a2dp_hal_clientif->IsValid()) {
605 LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP session=" << toString(session_type) << " is invalid?!";
606 delete a2dp_hal_clientif;
607 a2dp_hal_clientif = nullptr;
608 delete a2dp_sink;
609 a2dp_sink = nullptr;
610 return false;
611 }
612
Cheney Niad05f3e2018-11-08 16:41:02 +0800613 if (remote_delay != 0) {
614 LOG(INFO) << __func__ << ": restore DELAY "
615 << static_cast<float>(remote_delay / 10.0) << " ms";
616 a2dp_sink->SetRemoteDelay(remote_delay);
617 remote_delay = 0;
618 }
619 return true;
620}
621
622// Clean up BluetoothAudio HAL
623void cleanup() {
624 if (!is_hal_2_0_enabled()) return;
625 end_session();
626 delete a2dp_hal_clientif;
627 a2dp_hal_clientif = nullptr;
628 delete a2dp_sink;
629 a2dp_sink = nullptr;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800630 session_type = SessionType::UNKNOWN;
Cheney Niad05f3e2018-11-08 16:41:02 +0800631 remote_delay = 0;
632}
633
634// Set up the codec into BluetoothAudio HAL
635bool setup_codec() {
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800636 if (!is_hal_2_0_enabled()) {
637 LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
Cheney Niad05f3e2018-11-08 16:41:02 +0800638 return false;
639 }
Cheney Niad05f3e2018-11-08 16:41:02 +0800640 AudioConfiguration audio_config{};
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800641 if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
642 CodecConfiguration codec_config{};
643 if (!a2dp_get_selected_hal_codec_config(&codec_config)) {
644 LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration";
645 return false;
646 }
647 audio_config.codecConfig(codec_config);
648 } else if (session_type == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) {
649 PcmParameters pcm_config{};
650 if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) {
651 LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration";
652 return false;
653 }
Cheney Niad05f3e2018-11-08 16:41:02 +0800654 audio_config.pcmConfig(pcm_config);
Cheney Niad05f3e2018-11-08 16:41:02 +0800655 }
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800656 return a2dp_hal_clientif->UpdateAudioConfig(audio_config);
Cheney Niad05f3e2018-11-08 16:41:02 +0800657}
658
659void start_session() {
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800660 if (!is_hal_2_0_enabled()) {
661 LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
Cheney Niad05f3e2018-11-08 16:41:02 +0800662 return;
663 }
664 a2dp_hal_clientif->StartSession();
665}
666
667void end_session() {
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800668 if (!is_hal_2_0_enabled()) {
669 LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
Cheney Niad05f3e2018-11-08 16:41:02 +0800670 return;
671 }
672 a2dp_hal_clientif->EndSession();
673}
674
675void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
676 auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
677 LOG(INFO) << __func__ << ": result=" << ctrl_ack;
678 auto pending_cmd = a2dp_sink->GetPendingCmd();
679 if (pending_cmd == A2DP_CTRL_CMD_START) {
680 a2dp_hal_clientif->StreamStarted(ctrl_ack);
681 } else {
682 LOG(WARNING) << __func__ << ": pending=" << pending_cmd
683 << " ignore result=" << ctrl_ack;
684 return;
685 }
686 if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
687 a2dp_sink->ResetPendingCmd();
688 }
689}
690
691void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
692 auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
693 LOG(INFO) << __func__ << ": result=" << ctrl_ack;
694 auto pending_cmd = a2dp_sink->GetPendingCmd();
695 if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) {
696 a2dp_hal_clientif->StreamSuspended(ctrl_ack);
697 } else if (pending_cmd == A2DP_CTRL_CMD_STOP) {
698 LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack;
699 } else {
700 LOG(WARNING) << __func__ << ": pending=" << pending_cmd
701 << " ignore result=" << ctrl_ack;
702 return;
703 }
704 if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
705 a2dp_sink->ResetPendingCmd();
706 }
707}
708
709// Read from the FMQ of BluetoothAudio HAL
710size_t read(uint8_t* p_buf, uint32_t len) {
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -0800711 if (!is_hal_2_0_enabled()) {
712 LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
713 return 0;
714 } else if (session_type != SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) {
715 LOG(ERROR) << __func__ << ": session_type=" << toString(session_type)
716 << " is not A2DP_SOFTWARE_ENCODING_DATAPATH";
Cheney Niad05f3e2018-11-08 16:41:02 +0800717 return 0;
718 }
719 return a2dp_hal_clientif->ReadAudioData(p_buf, len);
720}
721
722// Update A2DP delay report to BluetoothAudio HAL
723void set_remote_delay(uint16_t delay_report) {
724 if (!is_hal_2_0_enabled()) {
725 LOG(INFO) << __func__ << ": not ready for DelayReport "
726 << static_cast<float>(delay_report / 10.0) << " ms";
727 remote_delay = delay_report;
728 return;
729 }
730 LOG(INFO) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0)
731 << " ms";
732 a2dp_sink->SetRemoteDelay(delay_report);
733}
734
735} // namespace a2dp
736} // namespace audio
737} // namespace bluetooth