1 /******************************************************************************
2  *
3  * Copyright 2019 HIMSA II K/S - www.himsa.com.Represented by EHIMA -
4  * www.ehima.com
5  * Copyright (c) 2022 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at:
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <bluetooth/log.h>
22 #include <com_android_bluetooth_flags.h>
23 #include <stdio.h>
24 
25 #include <chrono>
26 #include <cstddef>
27 #include <cstdint>
28 #include <functional>
29 #include <memory>
30 #include <mutex>
31 #include <optional>
32 #include <ostream>
33 #include <sstream>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 #include "audio/asrc/asrc_resampler.h"
39 #include "audio_hal_client.h"
40 #include "audio_hal_interface/le_audio_software.h"
41 #include "bta/le_audio/codec_manager.h"
42 #include "common/message_loop_thread.h"
43 #include "common/repeating_timer.h"
44 #include "common/time_util.h"
45 #include "hardware/bluetooth.h"
46 #include "le_audio/broadcaster/broadcaster_types.h"
47 #include "le_audio/le_audio_types.h"
48 #include "osi/include/wakelock.h"
49 #include "stack/include/main_thread.h"
50 
51 namespace bluetooth::le_audio {
52 namespace {
53 struct AudioHalStats {
54   size_t media_read_total_underflow_bytes;
55   size_t media_read_total_underflow_count;
56   uint64_t media_read_last_underflow_us;
57 
AudioHalStatsbluetooth::le_audio::__anoncec690b60111::AudioHalStats58   AudioHalStats() { Reset(); }
59 
Resetbluetooth::le_audio::__anoncec690b60111::AudioHalStats60   void Reset() {
61     media_read_total_underflow_bytes = 0;
62     media_read_total_underflow_count = 0;
63     media_read_last_underflow_us = 0;
64   }
65 } sStats;
66 
67 class SourceImpl : public LeAudioSourceAudioHalClient {
68   enum LeAudioSinkHalState {
69     HAL_UNINITIALIZED,
70     HAL_STOPPED,
71     HAL_STARTED,
72   } le_audio_sink_hal_state_;
73 
74 public:
75   // Interface implementation
76   bool Start(const LeAudioCodecConfiguration& codec_configuration,
77              LeAudioSourceAudioHalClient::Callbacks* audioReceiver, DsaModes dsa_modes) override;
78   void Stop() override;
79   void ConfirmStreamingRequest() override;
80   void CancelStreamingRequest() override;
81   void UpdateRemoteDelay(uint16_t remote_delay_ms) override;
82   void UpdateAudioConfigToHal(const ::bluetooth::le_audio::offload_config& config) override;
83   std::optional<broadcaster::BroadcastConfiguration> GetBroadcastConfig(
84           const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality,
85           const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>& pacs)
86           const override;
87   std::optional<::bluetooth::le_audio::set_configurations::AudioSetConfiguration> GetUnicastConfig(
88           const CodecManager::UnicastConfigurationRequirements& requirements) const override;
89   void UpdateBroadcastAudioConfigToHal(
90           const ::bluetooth::le_audio::broadcast_offload_config& config) override;
91   void SuspendedForReconfiguration() override;
92   void ReconfigurationComplete() override;
93 
94   // Internal functionality
SourceImpl(bool is_broadcaster)95   SourceImpl(bool is_broadcaster)
96       : le_audio_sink_hal_state_(HAL_UNINITIALIZED),
97         audio_timer_(
98                 /* clock_tick_us= */ bluetooth::common::time_get_audio_server_tick_us),
99         is_broadcaster_(is_broadcaster) {}
~SourceImpl()100   ~SourceImpl() override {
101     if (le_audio_sink_hal_state_ != HAL_UNINITIALIZED) {
102       Release();
103     }
104   }
105 
106   bool OnResumeReq(bool start_media_task);
107   bool OnSuspendReq();
108   bool OnMetadataUpdateReq(const source_metadata_v7_t& source_metadata, DsaMode latency_mode);
109   bool Acquire();
110   void Release();
111   bool InitAudioSinkThread();
112 
113   bluetooth::common::MessageLoopThread* worker_thread_;
114   bluetooth::common::RepeatingTimer audio_timer_;
115   LeAudioCodecConfiguration source_codec_config_;
116   void StartAudioTicks();
117   void StopAudioTicks();
118   void SendAudioData();
119 
120   bool is_broadcaster_;
121 
122   bluetooth::audio::le_audio::LeAudioClientInterface::Sink* halSinkInterface_ = nullptr;
123   LeAudioSourceAudioHalClient::Callbacks* audioSourceCallbacks_ = nullptr;
124   std::mutex audioSourceCallbacksMutex_;
125   std::unique_ptr<bluetooth::audio::asrc::SourceAudioHalAsrc> asrc_;
126 
127   base::WeakPtrFactory<SourceImpl> weak_factory_{this};
128 };
129 
Acquire()130 bool SourceImpl::Acquire() {
131   auto sink_stream_cb = bluetooth::audio::le_audio::StreamCallbacks{
132           .on_resume_ = std::bind(&SourceImpl::OnResumeReq, this, std::placeholders::_1),
133           .on_suspend_ = std::bind(&SourceImpl::OnSuspendReq, this),
134           .on_metadata_update_ = std::bind(&SourceImpl::OnMetadataUpdateReq, this,
135                                            std::placeholders::_1, std::placeholders::_2),
136           .on_sink_metadata_update_ =
137                   [](const sink_metadata_v7_t& /*sink_metadata*/) {
138                     // TODO: update microphone configuration based on sink metadata
139                     return true;
140                   },
141   };
142 
143   /* Get pointer to singleton LE audio client interface */
144   auto halInterface = audio::le_audio::LeAudioClientInterface::Get();
145   if (halInterface == nullptr) {
146     log::error("Can't get LE Audio HAL interface");
147     return false;
148   }
149 
150   halSinkInterface_ = halInterface->GetSink(sink_stream_cb, get_main_thread(), is_broadcaster_);
151 
152   if (halSinkInterface_ == nullptr) {
153     log::error("Can't get Audio HAL Audio sink interface");
154     return false;
155   }
156 
157   log::info("");
158   le_audio_sink_hal_state_ = HAL_STOPPED;
159   return this->InitAudioSinkThread();
160 }
161 
Release()162 void SourceImpl::Release() {
163   if (le_audio_sink_hal_state_ == HAL_UNINITIALIZED) {
164     log::warn("Audio HAL Audio sink is not running");
165     return;
166   }
167 
168   log::info("");
169   worker_thread_->ShutDown();
170 
171   if (halSinkInterface_) {
172     if (le_audio_sink_hal_state_ == HAL_STARTED) {
173       halSinkInterface_->StopSession();
174       le_audio_sink_hal_state_ = HAL_STOPPED;
175     }
176 
177     halSinkInterface_->Cleanup();
178 
179     auto halInterface = audio::le_audio::LeAudioClientInterface::Get();
180     if (halInterface != nullptr) {
181       halInterface->ReleaseSink(halSinkInterface_);
182     } else {
183       log::error("Can't get LE Audio HAL interface");
184     }
185 
186     le_audio_sink_hal_state_ = HAL_UNINITIALIZED;
187     halSinkInterface_ = nullptr;
188   }
189 }
190 
OnResumeReq(bool)191 bool SourceImpl::OnResumeReq(bool /*start_media_task*/) {
192   std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
193   if (audioSourceCallbacks_ == nullptr) {
194     log::error("audioSourceCallbacks_ not set");
195     return false;
196   }
197   bt_status_t status =
198           do_in_main_thread(base::BindOnce(&LeAudioSourceAudioHalClient::Callbacks::OnAudioResume,
199                                            audioSourceCallbacks_->weak_factory_.GetWeakPtr()));
200   if (status == BT_STATUS_SUCCESS) {
201     return true;
202   }
203 
204   log::error("do_in_main_thread err={}", status);
205   return false;
206 }
207 
SendAudioData()208 void SourceImpl::SendAudioData() {
209   if (halSinkInterface_ == nullptr) {
210     log::error("Audio HAL Audio sink interface not acquired - aborting");
211     return;
212   }
213 
214   // 24 bit audio is aligned to 32bit
215   int bytes_per_sample = (source_codec_config_.bits_per_sample == 24)
216                                  ? 4
217                                  : (source_codec_config_.bits_per_sample / 8);
218   uint32_t bytes_per_tick = (source_codec_config_.num_channels * source_codec_config_.sample_rate *
219                              source_codec_config_.data_interval_us / 1000 * bytes_per_sample) /
220                             1000;
221   std::vector<uint8_t> data(bytes_per_tick);
222 
223   uint32_t bytes_read = halSinkInterface_->Read(data.data(), bytes_per_tick);
224   if (bytes_read < bytes_per_tick) {
225     sStats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read;
226     sStats.media_read_total_underflow_count++;
227     sStats.media_read_last_underflow_us = bluetooth::common::time_get_os_boottime_us();
228   }
229 
230   if (com::android::bluetooth::flags::leaudio_hal_client_asrc()) {
231     auto asrc_buffers = asrc_->Run(data);
232 
233     std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
234     for (auto buffer : asrc_buffers) {
235       if (audioSourceCallbacks_ != nullptr) {
236         audioSourceCallbacks_->OnAudioDataReady(*buffer);
237       }
238     }
239   } else {
240     std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
241     if (audioSourceCallbacks_ != nullptr) {
242       audioSourceCallbacks_->OnAudioDataReady(data);
243     }
244   }
245 }
246 
InitAudioSinkThread()247 bool SourceImpl::InitAudioSinkThread() {
248   const std::string thread_name = is_broadcaster_ ? "bt_le_audio_broadcast_sink_worker_thread"
249                                                   : "bt_le_audio_unicast_sink_worker_thread";
250   worker_thread_ = new bluetooth::common::MessageLoopThread(thread_name);
251 
252   worker_thread_->StartUp();
253   if (!worker_thread_->IsRunning()) {
254     log::error("Unable to start up the BLE audio sink worker thread");
255     return false;
256   }
257 
258   /* Schedule the rest of the operations */
259   if (!worker_thread_->EnableRealTimeScheduling()) {
260 #if defined(__ANDROID__)
261     log::fatal("Failed to increase media thread priority");
262 #endif
263   }
264 
265   return true;
266 }
267 
StartAudioTicks()268 void SourceImpl::StartAudioTicks() {
269   wakelock_acquire();
270   if (com::android::bluetooth::flags::leaudio_hal_client_asrc()) {
271     asrc_ = std::make_unique<bluetooth::audio::asrc::SourceAudioHalAsrc>(
272             worker_thread_, source_codec_config_.num_channels, source_codec_config_.sample_rate,
273             source_codec_config_.bits_per_sample, source_codec_config_.data_interval_us);
274   }
275   audio_timer_.SchedulePeriodic(
276           worker_thread_->GetWeakPtr(), FROM_HERE,
277           base::BindRepeating(&SourceImpl::SendAudioData, weak_factory_.GetWeakPtr()),
278           std::chrono::microseconds(source_codec_config_.data_interval_us));
279 }
280 
StopAudioTicks()281 void SourceImpl::StopAudioTicks() {
282   audio_timer_.CancelAndWait();
283   asrc_.reset(nullptr);
284   wakelock_release();
285 }
286 
OnSuspendReq()287 bool SourceImpl::OnSuspendReq() {
288   std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
289   if (CodecManager::GetInstance()->GetCodecLocation() == types::CodecLocation::HOST) {
290     if (com::android::bluetooth::flags::run_ble_audio_ticks_in_worker_thread()) {
291       worker_thread_->DoInThread(
292               FROM_HERE, base::BindOnce(&SourceImpl::StopAudioTicks, weak_factory_.GetWeakPtr()));
293     } else {
294       StopAudioTicks();
295     }
296   }
297 
298   if (audioSourceCallbacks_ == nullptr) {
299     log::error("audioSourceCallbacks_ not set");
300     return false;
301   }
302 
303   bt_status_t status =
304           do_in_main_thread(base::BindOnce(&LeAudioSourceAudioHalClient::Callbacks::OnAudioSuspend,
305                                            audioSourceCallbacks_->weak_factory_.GetWeakPtr()));
306   if (status == BT_STATUS_SUCCESS) {
307     return true;
308   }
309 
310   log::error("do_in_main_thread err={}", status);
311   return false;
312 }
313 
OnMetadataUpdateReq(const source_metadata_v7_t & source_metadata,DsaMode dsa_mode)314 bool SourceImpl::OnMetadataUpdateReq(const source_metadata_v7_t& source_metadata,
315                                      DsaMode dsa_mode) {
316   std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
317   if (audioSourceCallbacks_ == nullptr) {
318     log::error("audio receiver not started");
319     return false;
320   }
321 
322   std::vector<struct playback_track_metadata_v7> metadata(
323           source_metadata.tracks, source_metadata.tracks + source_metadata.track_count);
324 
325   bt_status_t status = do_in_main_thread(base::BindOnce(
326           &LeAudioSourceAudioHalClient::Callbacks::OnAudioMetadataUpdate,
327           audioSourceCallbacks_->weak_factory_.GetWeakPtr(), std::move(metadata), dsa_mode));
328   if (status == BT_STATUS_SUCCESS) {
329     return true;
330   }
331 
332   log::error("do_in_main_thread err={}", status);
333   return false;
334 }
335 
Start(const LeAudioCodecConfiguration & codec_configuration,LeAudioSourceAudioHalClient::Callbacks * audioReceiver,DsaModes dsa_modes)336 bool SourceImpl::Start(const LeAudioCodecConfiguration& codec_configuration,
337                        LeAudioSourceAudioHalClient::Callbacks* audioReceiver, DsaModes dsa_modes) {
338   if (!halSinkInterface_) {
339     log::error("Audio HAL Audio sink interface not acquired");
340     return false;
341   }
342 
343   if (le_audio_sink_hal_state_ == HAL_STARTED) {
344     log::error("Audio HAL Audio sink is already in use");
345     return false;
346   }
347 
348   log::info("bit rate: {}, num channels: {}, sample rate: {}, data interval: {}",
349             codec_configuration.bits_per_sample, codec_configuration.num_channels,
350             codec_configuration.sample_rate, codec_configuration.data_interval_us);
351 
352   sStats.Reset();
353 
354   /* Global config for periodic audio data */
355   source_codec_config_ = codec_configuration;
356   audio::le_audio::LeAudioClientInterface::PcmParameters pcmParameters = {
357           .data_interval_us = codec_configuration.data_interval_us,
358           .sample_rate = codec_configuration.sample_rate,
359           .bits_per_sample = codec_configuration.bits_per_sample,
360           .channels_count = codec_configuration.num_channels};
361 
362   halSinkInterface_->SetPcmParameters(pcmParameters);
363   audio::le_audio::LeAudioClientInterface::Get()->SetAllowedDsaModes(dsa_modes);
364   halSinkInterface_->StartSession();
365 
366   std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
367   audioSourceCallbacks_ = audioReceiver;
368   le_audio_sink_hal_state_ = HAL_STARTED;
369   return true;
370 }
371 
Stop()372 void SourceImpl::Stop() {
373   if (!halSinkInterface_) {
374     log::error("Audio HAL Audio sink interface already stopped");
375     return;
376   }
377 
378   if (le_audio_sink_hal_state_ != HAL_STARTED) {
379     log::error("Audio HAL Audio sink was not started!");
380     return;
381   }
382 
383   log::info("");
384 
385   halSinkInterface_->StopSession();
386   le_audio_sink_hal_state_ = HAL_STOPPED;
387 
388   if (CodecManager::GetInstance()->GetCodecLocation() == types::CodecLocation::HOST) {
389     if (com::android::bluetooth::flags::run_ble_audio_ticks_in_worker_thread()) {
390       worker_thread_->DoInThread(
391               FROM_HERE, base::BindOnce(&SourceImpl::StopAudioTicks, weak_factory_.GetWeakPtr()));
392     } else {
393       StopAudioTicks();
394     }
395   }
396 
397   std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
398   audioSourceCallbacks_ = nullptr;
399 }
400 
ConfirmStreamingRequest()401 void SourceImpl::ConfirmStreamingRequest() {
402   if ((halSinkInterface_ == nullptr) || (le_audio_sink_hal_state_ != HAL_STARTED)) {
403     log::error("Audio HAL Audio sink was not started!");
404     return;
405   }
406 
407   log::info("");
408   halSinkInterface_->ConfirmStreamingRequest();
409 
410   if (CodecManager::GetInstance()->GetCodecLocation() != types::CodecLocation::HOST) {
411     return;
412   }
413 
414   if (com::android::bluetooth::flags::run_ble_audio_ticks_in_worker_thread()) {
415     worker_thread_->DoInThread(
416             FROM_HERE, base::BindOnce(&SourceImpl::StartAudioTicks, weak_factory_.GetWeakPtr()));
417   } else {
418     StartAudioTicks();
419   }
420 }
421 
SuspendedForReconfiguration()422 void SourceImpl::SuspendedForReconfiguration() {
423   if ((halSinkInterface_ == nullptr) || (le_audio_sink_hal_state_ != HAL_STARTED)) {
424     log::error("Audio HAL Audio sink was not started!");
425     return;
426   }
427 
428   log::info("");
429   halSinkInterface_->SuspendedForReconfiguration();
430 }
431 
ReconfigurationComplete()432 void SourceImpl::ReconfigurationComplete() {
433   if ((halSinkInterface_ == nullptr) || (le_audio_sink_hal_state_ != HAL_STARTED)) {
434     log::error("Audio HAL Audio sink was not started!");
435     return;
436   }
437 
438   log::info("");
439   halSinkInterface_->ReconfigurationComplete();
440 }
441 
CancelStreamingRequest()442 void SourceImpl::CancelStreamingRequest() {
443   if ((halSinkInterface_ == nullptr) || (le_audio_sink_hal_state_ != HAL_STARTED)) {
444     log::error("Audio HAL Audio sink was not started!");
445     return;
446   }
447 
448   log::info("");
449   halSinkInterface_->CancelStreamingRequest();
450 }
451 
UpdateRemoteDelay(uint16_t remote_delay_ms)452 void SourceImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) {
453   if ((halSinkInterface_ == nullptr) || (le_audio_sink_hal_state_ != HAL_STARTED)) {
454     log::error("Audio HAL Audio sink was not started!");
455     return;
456   }
457 
458   log::info("");
459   halSinkInterface_->SetRemoteDelay(remote_delay_ms);
460 }
461 
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config & config)462 void SourceImpl::UpdateAudioConfigToHal(const ::bluetooth::le_audio::offload_config& config) {
463   if ((halSinkInterface_ == nullptr) || (le_audio_sink_hal_state_ != HAL_STARTED)) {
464     log::error("Audio HAL Audio sink was not started!");
465     return;
466   }
467 
468   log::info("");
469   halSinkInterface_->UpdateAudioConfigToHal(config);
470 }
471 
GetBroadcastConfig(const std::vector<std::pair<types::LeAudioContextType,uint8_t>> & subgroup_quality,const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>> & pacs) const472 std::optional<broadcaster::BroadcastConfiguration> SourceImpl::GetBroadcastConfig(
473         const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality,
474         const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>& pacs) const {
475   if (halSinkInterface_ == nullptr) {
476     log::error("Audio HAL Audio sink is null!");
477     return std::nullopt;
478   }
479 
480   log::info("");
481   return halSinkInterface_->GetBroadcastConfig(subgroup_quality, pacs);
482 }
483 
484 std::optional<::bluetooth::le_audio::set_configurations::AudioSetConfiguration>
GetUnicastConfig(const CodecManager::UnicastConfigurationRequirements & requirements) const485 SourceImpl::GetUnicastConfig(
486         const CodecManager::UnicastConfigurationRequirements& requirements) const {
487   if (halSinkInterface_ == nullptr) {
488     log::error("Audio HAL Audio sink is null!");
489     return std::nullopt;
490   }
491 
492   log::info("");
493   return halSinkInterface_->GetUnicastConfig(requirements);
494 }
495 
UpdateBroadcastAudioConfigToHal(const::bluetooth::le_audio::broadcast_offload_config & config)496 void SourceImpl::UpdateBroadcastAudioConfigToHal(
497         const ::bluetooth::le_audio::broadcast_offload_config& config) {
498   if (halSinkInterface_ == nullptr) {
499     log::error("Audio HAL Audio sink interface not acquired");
500     return;
501   }
502 
503   log::info("");
504   halSinkInterface_->UpdateBroadcastAudioConfigToHal(config);
505 }
506 }  // namespace
507 
AcquireUnicast()508 std::unique_ptr<LeAudioSourceAudioHalClient> LeAudioSourceAudioHalClient::AcquireUnicast() {
509   std::unique_ptr<SourceImpl> impl(new SourceImpl(false));
510   if (!impl->Acquire()) {
511     log::error("Could not acquire Unicast Source on LE Audio HAL enpoint");
512     impl.reset();
513     return nullptr;
514   }
515 
516   log::info("");
517   return std::move(impl);
518 }
519 
AcquireBroadcast()520 std::unique_ptr<LeAudioSourceAudioHalClient> LeAudioSourceAudioHalClient::AcquireBroadcast() {
521   std::unique_ptr<SourceImpl> impl(new SourceImpl(true));
522   if (!impl->Acquire()) {
523     log::error("Could not acquire Broadcast Source on LE Audio HAL endpoint");
524     impl.reset();
525     return nullptr;
526   }
527 
528   log::info("");
529   return std::move(impl);
530 }
531 
DebugDump(int fd)532 void LeAudioSourceAudioHalClient::DebugDump(int fd) {
533   uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
534   std::stringstream stream;
535   stream << "  LE AudioHalClient:"
536          << "\n    Counts (underflow)                                      : "
537          << sStats.media_read_total_underflow_count
538          << "\n    Bytes (underflow)                                       : "
539          << sStats.media_read_total_underflow_bytes
540          << "\n    Last update time ago in ms (underflow)                  : "
541          << (sStats.media_read_last_underflow_us > 0
542                      ? (now_us - sStats.media_read_last_underflow_us) / 1000
543                      : 0)
544          << std::endl;
545   dprintf(fd, "%s", stream.str().c_str());
546 }
547 }  // namespace bluetooth::le_audio
548