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