1 /*
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 #define LOG_TAG "BTAudioA2dpHIDL"
17
18 #include "a2dp_encoding_hidl.h"
19
20 #include <bluetooth/log.h>
21
22 #include <vector>
23
24 #include "a2dp_sbc_constants.h"
25 #include "client_interface_hidl.h"
26 #include "codec_status_hidl.h"
27 #include "osi/include/properties.h"
28 #include "types/raw_address.h"
29
30 typedef enum {
31 A2DP_CTRL_CMD_NONE,
32 A2DP_CTRL_CMD_CHECK_READY,
33 A2DP_CTRL_CMD_START,
34 A2DP_CTRL_CMD_STOP,
35 A2DP_CTRL_CMD_SUSPEND,
36 A2DP_CTRL_GET_INPUT_AUDIO_CONFIG,
37 A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG,
38 A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
39 A2DP_CTRL_GET_PRESENTATION_POSITION,
40 } tA2DP_CTRL_CMD;
41
42 namespace std {
43 template <>
44 struct formatter<tA2DP_CTRL_CMD> : enum_formatter<tA2DP_CTRL_CMD> {};
45 template <>
46 struct formatter<audio_usage_t> : enum_formatter<audio_usage_t> {};
47 template <>
48 struct formatter<audio_content_type_t> : enum_formatter<audio_content_type_t> {};
49 } // namespace std
50
51 namespace bluetooth {
52 namespace audio {
53 namespace hidl {
54 namespace a2dp {
55
56 static bluetooth::audio::a2dp::StreamCallbacks null_stream_callbacks;
57 static bluetooth::audio::a2dp::StreamCallbacks const* stream_callbacks_ = &null_stream_callbacks;
58
59 namespace {
60
61 using ::bluetooth::audio::hidl::AudioCapabilities;
62 using ::bluetooth::audio::hidl::AudioConfiguration;
63 using ::bluetooth::audio::hidl::BitsPerSample;
64 using ::bluetooth::audio::hidl::BluetoothAudioCtrlAck;
65 using ::bluetooth::audio::hidl::ChannelMode;
66 using ::bluetooth::audio::hidl::PcmParameters;
67 using ::bluetooth::audio::hidl::SampleRate;
68 using ::bluetooth::audio::hidl::SessionType;
69
70 using ::bluetooth::audio::hidl::BluetoothAudioSinkClientInterface;
71 using ::bluetooth::audio::hidl::codec::A2dpAacToHalConfig;
72 using ::bluetooth::audio::hidl::codec::A2dpAptxToHalConfig;
73 using ::bluetooth::audio::hidl::codec::A2dpCodecToHalBitsPerSample;
74 using ::bluetooth::audio::hidl::codec::A2dpCodecToHalChannelMode;
75 using ::bluetooth::audio::hidl::codec::A2dpCodecToHalSampleRate;
76 using ::bluetooth::audio::hidl::codec::A2dpLdacToHalConfig;
77 using ::bluetooth::audio::hidl::codec::A2dpSbcToHalConfig;
78 using ::bluetooth::audio::hidl::codec::CodecConfiguration;
79
80 using ::bluetooth::audio::a2dp::Status;
81
a2dp_ack_to_bt_audio_ctrl_ack(Status ack)82 static BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(Status ack) {
83 switch (ack) {
84 case Status::SUCCESS:
85 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
86 case Status::PENDING:
87 return BluetoothAudioCtrlAck::PENDING;
88 case Status::UNSUPPORTED_CODEC_CONFIGURATION:
89 return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
90 case Status::UNKNOWN:
91 case Status::FAILURE:
92 default:
93 return BluetoothAudioCtrlAck::FAILURE;
94 }
95 }
96
97 // Provide call-in APIs for the Bluetooth Audio HAL
98 class A2dpTransport : public ::bluetooth::audio::hidl::IBluetoothSinkTransportInstance {
99 public:
A2dpTransport(SessionType sessionType)100 A2dpTransport(SessionType sessionType)
101 : IBluetoothSinkTransportInstance(sessionType, (AudioConfiguration){}),
102 total_bytes_read_(0),
103 data_position_({}) {
104 a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
105 remote_delay_report_ = 0;
106 }
107
StartRequest()108 BluetoothAudioCtrlAck StartRequest() override {
109 // Check if a previous Start request is ongoing.
110 if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
111 log::warn("unable to start stream: already pending");
112 return BluetoothAudioCtrlAck::PENDING;
113 }
114
115 // Check if a different request is ongoing.
116 if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
117 log::warn("unable to start stream: busy with pending command {}", a2dp_pending_cmd_);
118 return BluetoothAudioCtrlAck::FAILURE;
119 }
120
121 log::info("");
122
123 auto status = stream_callbacks_->StartStream(false);
124 a2dp_pending_cmd_ = status == Status::PENDING ? A2DP_CTRL_CMD_START : A2DP_CTRL_CMD_NONE;
125
126 return a2dp_ack_to_bt_audio_ctrl_ack(status);
127 }
128
SuspendRequest()129 BluetoothAudioCtrlAck SuspendRequest() override {
130 // Check if a previous Suspend request is ongoing.
131 if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
132 log::warn("unable to suspend stream: already pending");
133 return BluetoothAudioCtrlAck::PENDING;
134 }
135
136 // Check if a different request is ongoing.
137 if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
138 log::warn("unable to suspend stream: busy with pending command {}", a2dp_pending_cmd_);
139 return BluetoothAudioCtrlAck::FAILURE;
140 }
141
142 log::info("");
143
144 auto status = stream_callbacks_->SuspendStream();
145 a2dp_pending_cmd_ = status == Status::PENDING ? A2DP_CTRL_CMD_SUSPEND : A2DP_CTRL_CMD_NONE;
146
147 return a2dp_ack_to_bt_audio_ctrl_ack(status);
148 }
149
StopRequest()150 void StopRequest() override {
151 log::info("");
152
153 auto status = stream_callbacks_->SuspendStream();
154 a2dp_pending_cmd_ = status == Status::PENDING ? A2DP_CTRL_CMD_STOP : A2DP_CTRL_CMD_NONE;
155 }
156
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)157 bool GetPresentationPosition(uint64_t* remote_delay_report_ns, uint64_t* total_bytes_read,
158 timespec* data_position) override {
159 *remote_delay_report_ns = remote_delay_report_ * 100000u;
160 *total_bytes_read = total_bytes_read_;
161 *data_position = data_position_;
162 log::verbose("delay={}/10ms, data={} byte(s), timestamp={}.{}s", remote_delay_report_,
163 total_bytes_read_, data_position_.tv_sec, data_position_.tv_nsec);
164 return true;
165 }
166
MetadataChanged(const source_metadata_t & source_metadata)167 void MetadataChanged(const source_metadata_t& source_metadata) override {
168 auto track_count = source_metadata.track_count;
169 auto tracks = source_metadata.tracks;
170 log::verbose("{} track(s) received", track_count);
171 while (track_count) {
172 log::verbose("usage={}, content_type={}, gain={}", tracks->usage, tracks->content_type,
173 tracks->gain);
174 --track_count;
175 ++tracks;
176 }
177 }
178
GetPendingCmd() const179 tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
180
ResetPendingCmd()181 void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
182
ResetPresentationPosition()183 void ResetPresentationPosition() override {
184 remote_delay_report_ = 0;
185 total_bytes_read_ = 0;
186 data_position_ = {};
187 }
188
LogBytesRead(size_t bytes_read)189 void LogBytesRead(size_t bytes_read) override {
190 if (bytes_read != 0) {
191 total_bytes_read_ += bytes_read;
192 clock_gettime(CLOCK_MONOTONIC, &data_position_);
193 }
194 }
195
196 // delay reports from AVDTP is based on 1/10 ms (100us)
SetRemoteDelay(uint16_t delay_report)197 void SetRemoteDelay(uint16_t delay_report) { remote_delay_report_ = delay_report; }
198
199 private:
200 static tA2DP_CTRL_CMD a2dp_pending_cmd_;
201 static uint16_t remote_delay_report_;
202 uint64_t total_bytes_read_;
203 timespec data_position_;
204 };
205
206 tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
207 uint16_t A2dpTransport::remote_delay_report_ = 0;
208
209 // Common interface to call-out into Bluetooth Audio HAL
210 BluetoothAudioSinkClientInterface* software_hal_interface = nullptr;
211 BluetoothAudioSinkClientInterface* offloading_hal_interface = nullptr;
212 BluetoothAudioSinkClientInterface* active_hal_interface = nullptr;
213
214 // Save the value if the remote reports its delay before this interface is
215 // initialized
216 uint16_t remote_delay = 0;
217
a2dp_get_selected_hal_codec_config(A2dpCodecConfig * a2dp_config,uint16_t peer_mtu,CodecConfiguration * codec_config)218 static bool a2dp_get_selected_hal_codec_config(A2dpCodecConfig* a2dp_config, uint16_t peer_mtu,
219 CodecConfiguration* codec_config) {
220 btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
221 switch (current_codec.codec_type) {
222 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
223 [[fallthrough]];
224 case BTAV_A2DP_CODEC_INDEX_SINK_SBC: {
225 if (!A2dpSbcToHalConfig(codec_config, a2dp_config)) {
226 return false;
227 }
228 break;
229 }
230 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
231 [[fallthrough]];
232 case BTAV_A2DP_CODEC_INDEX_SINK_AAC: {
233 if (!A2dpAacToHalConfig(codec_config, a2dp_config)) {
234 return false;
235 }
236 break;
237 }
238 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
239 [[fallthrough]];
240 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: {
241 if (!A2dpAptxToHalConfig(codec_config, a2dp_config)) {
242 return false;
243 }
244 break;
245 }
246 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: {
247 if (!A2dpLdacToHalConfig(codec_config, a2dp_config)) {
248 return false;
249 }
250 break;
251 }
252 case BTAV_A2DP_CODEC_INDEX_MAX:
253 [[fallthrough]];
254 default:
255 log::error("Unknown codec_type={}", current_codec.codec_type);
256 *codec_config = ::bluetooth::audio::hidl::codec::kInvalidCodecConfiguration;
257 return false;
258 }
259 codec_config->encodedAudioBitrate = a2dp_config->getTrackBitRate();
260 codec_config->peerMtu = peer_mtu;
261 log::info("CodecConfiguration={}", toString(*codec_config));
262 return true;
263 }
264
a2dp_get_selected_hal_pcm_config(A2dpCodecConfig * a2dp_codec_configs,PcmParameters * pcm_config)265 static bool a2dp_get_selected_hal_pcm_config(A2dpCodecConfig* a2dp_codec_configs,
266 PcmParameters* pcm_config) {
267 if (pcm_config == nullptr) {
268 return false;
269 }
270
271 btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
272 pcm_config->sampleRate = A2dpCodecToHalSampleRate(current_codec);
273 pcm_config->bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
274 pcm_config->channelMode = A2dpCodecToHalChannelMode(current_codec);
275 return pcm_config->sampleRate != SampleRate::RATE_UNKNOWN &&
276 pcm_config->bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
277 pcm_config->channelMode != ChannelMode::UNKNOWN;
278 }
279
280 } // namespace
281
update_codec_offloading_capabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference)282 bool update_codec_offloading_capabilities(
283 const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
284 return ::bluetooth::audio::hidl::codec::UpdateOffloadingCapabilities(framework_preference);
285 }
286
287 // Checking if new bluetooth_audio is enabled
is_hal_2_0_enabled()288 bool is_hal_2_0_enabled() { return active_hal_interface != nullptr; }
289
290 // Check if new bluetooth_audio is running with offloading encoders
is_hal_2_0_offloading()291 bool is_hal_2_0_offloading() {
292 if (!is_hal_2_0_enabled()) {
293 return false;
294 }
295 return active_hal_interface->GetTransportInstance()->GetSessionType() ==
296 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
297 }
298
299 // Initialize BluetoothAudio HAL: openProvider
init(bluetooth::common::MessageLoopThread * message_loop,bluetooth::audio::a2dp::StreamCallbacks const * stream_callbacks,bool offload_enabled)300 bool init(bluetooth::common::MessageLoopThread* message_loop,
301 bluetooth::audio::a2dp::StreamCallbacks const* stream_callbacks, bool offload_enabled) {
302 log::info("");
303 log::assert_that(stream_callbacks != nullptr, "stream_callbacks != nullptr");
304
305 auto a2dp_sink = new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
306 software_hal_interface = new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
307 if (!software_hal_interface->IsValid()) {
308 log::warn("BluetoothAudio HAL for A2DP is invalid?!");
309 delete software_hal_interface;
310 software_hal_interface = nullptr;
311 delete a2dp_sink;
312 return false;
313 }
314
315 if (offload_enabled) {
316 a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
317 offloading_hal_interface = new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
318 if (!offloading_hal_interface->IsValid()) {
319 log::fatal("BluetoothAudio HAL for A2DP offloading is invalid?!");
320 delete offloading_hal_interface;
321 offloading_hal_interface = nullptr;
322 delete a2dp_sink;
323 a2dp_sink = static_cast<A2dpTransport*>(software_hal_interface->GetTransportInstance());
324 delete software_hal_interface;
325 software_hal_interface = nullptr;
326 delete a2dp_sink;
327 return false;
328 }
329 }
330
331 stream_callbacks_ = stream_callbacks;
332 active_hal_interface =
333 (offloading_hal_interface != nullptr ? offloading_hal_interface : software_hal_interface);
334
335 if (remote_delay != 0) {
336 log::info("restore DELAY {} ms", static_cast<float>(remote_delay / 10.0));
337 static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
338 ->SetRemoteDelay(remote_delay);
339 remote_delay = 0;
340 }
341 return true;
342 }
343
344 // Clean up BluetoothAudio HAL
cleanup()345 void cleanup() {
346 if (!is_hal_2_0_enabled()) {
347 return;
348 }
349 end_session();
350
351 auto a2dp_sink = active_hal_interface->GetTransportInstance();
352 static_cast<A2dpTransport*>(a2dp_sink)->ResetPendingCmd();
353 static_cast<A2dpTransport*>(a2dp_sink)->ResetPresentationPosition();
354 active_hal_interface = nullptr;
355
356 a2dp_sink = software_hal_interface->GetTransportInstance();
357 delete software_hal_interface;
358 software_hal_interface = nullptr;
359 delete a2dp_sink;
360 if (offloading_hal_interface != nullptr) {
361 a2dp_sink = offloading_hal_interface->GetTransportInstance();
362 delete offloading_hal_interface;
363 offloading_hal_interface = nullptr;
364 delete a2dp_sink;
365 }
366
367 stream_callbacks_ = &null_stream_callbacks;
368 remote_delay = 0;
369 }
370
371 // Set up the codec into BluetoothAudio HAL
setup_codec(A2dpCodecConfig * a2dp_config,uint16_t peer_mtu,int)372 bool setup_codec(A2dpCodecConfig* a2dp_config, uint16_t peer_mtu,
373 int /*preferred_encoding_interval_us*/) {
374 log::assert_that(a2dp_config != nullptr, "received invalid codec configuration");
375
376 if (!is_hal_2_0_enabled()) {
377 log::error("BluetoothAudio HAL is not enabled");
378 return false;
379 }
380 CodecConfiguration codec_config{};
381 if (!a2dp_get_selected_hal_codec_config(a2dp_config, peer_mtu, &codec_config)) {
382 log::error("Failed to get CodecConfiguration");
383 return false;
384 }
385 bool should_codec_offloading =
386 bluetooth::audio::hidl::codec::IsCodecOffloadingEnabled(codec_config);
387 if (should_codec_offloading && !is_hal_2_0_offloading()) {
388 log::warn("Switching BluetoothAudio HAL to Hardware");
389 end_session();
390 active_hal_interface = offloading_hal_interface;
391 } else if (!should_codec_offloading && is_hal_2_0_offloading()) {
392 log::warn("Switching BluetoothAudio HAL to Software");
393 end_session();
394 active_hal_interface = software_hal_interface;
395 }
396
397 AudioConfiguration audio_config{};
398 if (active_hal_interface->GetTransportInstance()->GetSessionType() ==
399 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
400 audio_config.codecConfig(codec_config);
401 } else {
402 PcmParameters pcm_config{};
403 if (!a2dp_get_selected_hal_pcm_config(a2dp_config, &pcm_config)) {
404 log::error("Failed to get PcmConfiguration");
405 return false;
406 }
407 audio_config.pcmConfig(pcm_config);
408 }
409 return active_hal_interface->UpdateAudioConfig(audio_config);
410 }
411
start_session()412 void start_session() {
413 if (!is_hal_2_0_enabled()) {
414 log::error("BluetoothAudio HAL is not enabled");
415 return;
416 }
417 active_hal_interface->StartSession();
418 }
419
end_session()420 void end_session() {
421 if (!is_hal_2_0_enabled()) {
422 log::error("BluetoothAudio HAL is not enabled");
423 return;
424 }
425 active_hal_interface->EndSession();
426 static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())->ResetPendingCmd();
427 static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
428 ->ResetPresentationPosition();
429 }
430
ack_stream_started(Status ack)431 void ack_stream_started(Status ack) {
432 if (!is_hal_2_0_enabled()) {
433 log::error("BluetoothAudio HAL is not enabled");
434 return;
435 }
436 log::info("result={}", ack);
437 auto a2dp_sink = static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
438 auto pending_cmd = a2dp_sink->GetPendingCmd();
439 if (pending_cmd == A2DP_CTRL_CMD_START) {
440 active_hal_interface->StreamStarted(a2dp_ack_to_bt_audio_ctrl_ack(ack));
441 } else {
442 log::warn("pending={} ignore result={}", pending_cmd, ack);
443 return;
444 }
445 if (ack != Status::PENDING) {
446 a2dp_sink->ResetPendingCmd();
447 }
448 }
449
ack_stream_suspended(Status ack)450 void ack_stream_suspended(Status ack) {
451 if (!is_hal_2_0_enabled()) {
452 log::error("BluetoothAudio HAL is not enabled");
453 return;
454 }
455 log::info("result={}", ack);
456 auto a2dp_sink = static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
457 auto pending_cmd = a2dp_sink->GetPendingCmd();
458 if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) {
459 active_hal_interface->StreamSuspended(a2dp_ack_to_bt_audio_ctrl_ack(ack));
460 } else if (pending_cmd == A2DP_CTRL_CMD_STOP) {
461 log::info("A2DP_CTRL_CMD_STOP result={}", ack);
462 } else {
463 log::warn("pending={} ignore result={}", pending_cmd, ack);
464 return;
465 }
466 if (ack != Status::PENDING) {
467 a2dp_sink->ResetPendingCmd();
468 }
469 }
470
471 // Read from the FMQ of BluetoothAudio HAL
read(uint8_t * p_buf,uint32_t len)472 size_t read(uint8_t* p_buf, uint32_t len) {
473 if (!is_hal_2_0_enabled()) {
474 log::error("BluetoothAudio HAL is not enabled");
475 return 0;
476 }
477 if (is_hal_2_0_offloading()) {
478 log::error("session_type={} is not A2DP_SOFTWARE_ENCODING_DATAPATH",
479 toString(active_hal_interface->GetTransportInstance()->GetSessionType()));
480 return 0;
481 }
482 return active_hal_interface->ReadAudioData(p_buf, len);
483 }
484
485 // Update A2DP delay report to BluetoothAudio HAL
set_remote_delay(uint16_t delay_report)486 void set_remote_delay(uint16_t delay_report) {
487 if (!is_hal_2_0_enabled()) {
488 log::info("not ready for DelayReport {} ms", static_cast<float>(delay_report / 10.0));
489 remote_delay = delay_report;
490 return;
491 }
492 log::verbose("DELAY {} ms", static_cast<float>(delay_report / 10.0));
493 static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
494 ->SetRemoteDelay(delay_report);
495 }
496
497 } // namespace a2dp
498 } // namespace hidl
499 } // namespace audio
500 } // namespace bluetooth
501