1 /*
2  * Copyright 2023 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 
17 #include <cstdint>
18 
19 #define LOG_TAG "BTAudioClientHfpStub"
20 
21 #include <bluetooth/log.h>
22 
23 #include "aidl/client_interface_aidl.h"
24 #include "aidl/hfp_client_interface_aidl.h"
25 #include "hal_version_manager.h"
26 #include "hfp_client_interface.h"
27 #include "osi/include/properties.h"
28 
29 using ::bluetooth::audio::aidl::hfp::HfpDecodingTransport;
30 using ::bluetooth::audio::aidl::hfp::HfpEncodingTransport;
31 using AudioConfiguration = ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
32 using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
33 using ::aidl::android::hardware::bluetooth::audio::CodecId;
34 using ::aidl::android::hardware::bluetooth::audio::HfpConfiguration;
35 using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
36 
37 namespace bluetooth {
38 namespace audio {
39 namespace hfp {
40 
get_decode_client_interface()41 static aidl::BluetoothAudioSourceClientInterface* get_decode_client_interface() {
42   return HfpDecodingTransport::active_hal_interface;
43 }
44 
get_encode_client_interface()45 static aidl::BluetoothAudioSinkClientInterface* get_encode_client_interface() {
46   return HfpEncodingTransport::active_hal_interface;
47 }
48 
get_decode_transport_instance()49 static HfpDecodingTransport* get_decode_transport_instance() {
50   return HfpDecodingTransport::instance_;
51 }
52 
get_encode_transport_instance()53 static HfpDecodingTransport* get_encode_transport_instance() {
54   return HfpDecodingTransport::instance_;
55 }
56 
get_default_pcm_configuration()57 static PcmConfiguration get_default_pcm_configuration() {
58   PcmConfiguration pcm_config{
59           .sampleRateHz = 8000,
60           .channelMode = ChannelMode::MONO,
61           .bitsPerSample = 16,
62           .dataIntervalUs = 7500,
63   };
64   return pcm_config;
65 }
66 
get_default_hfp_configuration()67 static HfpConfiguration get_default_hfp_configuration() {
68   HfpConfiguration hfp_config{
69           .codecId = CodecId::Core::CVSD,
70           .connectionHandle = 6,
71           .nrec = false,
72           .controllerCodec = true,
73   };
74   return hfp_config;
75 }
76 
sco_codec_to_hal_codec(tBTA_AG_UUID_CODEC sco_codec)77 static CodecId sco_codec_to_hal_codec(tBTA_AG_UUID_CODEC sco_codec) {
78   switch (sco_codec) {
79     case tBTA_AG_UUID_CODEC::UUID_CODEC_LC3:
80       return CodecId::Core::LC3;
81     case tBTA_AG_UUID_CODEC::UUID_CODEC_MSBC:
82       return CodecId::Core::MSBC;
83     case tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD:
84       return CodecId::Core::CVSD;
85     default:
86       log::warn("Unknown sco_codec {}, defaulting to vendor codec",
87                 bta_ag_uuid_codec_text(sco_codec));
88       return CodecId::Vendor();
89   }
90 }
91 
offload_config_to_hal_audio_config(const::hfp::offload_config & offload_config)92 static AudioConfiguration offload_config_to_hal_audio_config(
93         const ::hfp::offload_config& offload_config) {
94   HfpConfiguration hfp_config{
95           .codecId = sco_codec_to_hal_codec(offload_config.sco_codec),
96           .connectionHandle = offload_config.connection_handle,
97           .nrec = offload_config.is_nrec,
98           .controllerCodec = offload_config.is_controller_codec,
99   };
100   return AudioConfiguration(hfp_config);
101 }
102 
pcm_config_to_hal_audio_config(const::hfp::pcm_config & pcm_config)103 static AudioConfiguration pcm_config_to_hal_audio_config(const ::hfp::pcm_config& pcm_config) {
104   PcmConfiguration config = get_default_pcm_configuration();
105   config.sampleRateHz = pcm_config.sample_rate_hz;
106   return AudioConfiguration(config);
107 }
108 
is_aidl_support_hfp()109 static bool is_aidl_support_hfp() {
110   return HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL &&
111          HalVersionManager::GetHalVersion() >= BluetoothAudioHalVersion::VERSION_AIDL_V4;
112 }
113 
114 // Parent client implementation
115 HfpClientInterface* HfpClientInterface::interface = nullptr;
Get()116 HfpClientInterface* HfpClientInterface::Get() {
117   if (!is_aidl_support_hfp()) {
118     log::warn("Unsupported HIDL or AIDL version");
119     return nullptr;
120   }
121   if (HfpClientInterface::interface == nullptr) {
122     HfpClientInterface::interface = new HfpClientInterface();
123   }
124   return HfpClientInterface::interface;
125 }
126 
127 // Decode client implementation
Cleanup()128 void HfpClientInterface::Decode::Cleanup() {
129   log::info("decode");
130   StopSession();
131   if (HfpDecodingTransport::instance_) {
132     delete HfpDecodingTransport::software_hal_interface;
133     HfpDecodingTransport::software_hal_interface = nullptr;
134     delete HfpDecodingTransport::instance_;
135     HfpDecodingTransport::instance_ = nullptr;
136   }
137 }
138 
StartSession()139 void HfpClientInterface::Decode::StartSession() {
140   if (!is_aidl_support_hfp()) {
141     log::warn("Unsupported HIDL or AIDL version");
142     return;
143   }
144   log::info("decode");
145   AudioConfiguration audio_config;
146   audio_config.set<AudioConfiguration::pcmConfig>(get_default_pcm_configuration());
147   if (!get_decode_client_interface()->UpdateAudioConfig(audio_config)) {
148     log::error("cannot update audio config to HAL");
149     return;
150   }
151   auto instance = aidl::hfp::HfpEncodingTransport::instance_;
152   instance->ResetPendingCmd();
153   get_decode_client_interface()->StartSession();
154 }
155 
StopSession()156 void HfpClientInterface::Decode::StopSession() {
157   if (!is_aidl_support_hfp()) {
158     log::warn("Unsupported HIDL or AIDL version");
159     return;
160   }
161   log::info("decode");
162   get_decode_client_interface()->EndSession();
163   if (get_decode_transport_instance()) {
164     get_decode_transport_instance()->ResetPendingCmd();
165     get_decode_transport_instance()->ResetPresentationPosition();
166   }
167 }
168 
UpdateAudioConfigToHal(const::hfp::offload_config &)169 void HfpClientInterface::Decode::UpdateAudioConfigToHal(
170         const ::hfp::offload_config& /*offload_config*/) {
171   log::warn(
172           "'UpdateAudioConfigToHal(offload_config)' should not be called on "
173           "HfpClientInterface::Decode");
174 }
175 
UpdateAudioConfigToHal(const::hfp::pcm_config & pcm_config)176 void HfpClientInterface::Decode::UpdateAudioConfigToHal(const ::hfp::pcm_config& pcm_config) {
177   if (!is_aidl_support_hfp()) {
178     log::warn("Unsupported HIDL or AIDL version");
179     return;
180   }
181 
182   log::info("decode");
183   if (!get_decode_client_interface()->UpdateAudioConfig(
184               pcm_config_to_hal_audio_config(pcm_config))) {
185     log::error("cannot update audio config to HAL");
186     return;
187   }
188 }
189 
Write(const uint8_t * p_buf,uint32_t len)190 size_t HfpClientInterface::Decode::Write(const uint8_t* p_buf, uint32_t len) {
191   if (!is_aidl_support_hfp()) {
192     log::warn("Unsupported HIDL or AIDL version");
193     return 0;
194   }
195   log::verbose("decode");
196 
197   auto instance = aidl::hfp::HfpDecodingTransport::instance_;
198   if (instance->IsStreamActive()) {
199     return get_decode_client_interface()->WriteAudioData(p_buf, len);
200   }
201 
202   return len;
203 }
204 
ConfirmStreamingRequest()205 void HfpClientInterface::Decode::ConfirmStreamingRequest() {
206   auto instance = aidl::hfp::HfpDecodingTransport::instance_;
207   auto pending_cmd = instance->GetPendingCmd();
208   switch (pending_cmd) {
209     case aidl::hfp::HFP_CTRL_CMD_NONE:
210       log::warn("no pending start stream request");
211       FALLTHROUGH_INTENDED;
212     case aidl::hfp::HFP_CTRL_CMD_START:
213       aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamStarted(
214               aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
215       instance->ResetPendingCmd();
216       return;
217     default:
218       log::warn("Invalid state, {}", pending_cmd);
219   }
220 }
221 
CancelStreamingRequest()222 void HfpClientInterface::Decode::CancelStreamingRequest() {
223   auto instance = aidl::hfp::HfpDecodingTransport::instance_;
224   auto pending_cmd = instance->GetPendingCmd();
225   switch (pending_cmd) {
226     case aidl::hfp::HFP_CTRL_CMD_START:
227       aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamStarted(
228               aidl::BluetoothAudioCtrlAck::FAILURE);
229       instance->ResetPendingCmd();
230       return;
231     case aidl::hfp::HFP_CTRL_CMD_NONE:
232       log::warn("no pending start stream request");
233       FALLTHROUGH_INTENDED;
234     case aidl::hfp::HFP_CTRL_CMD_SUSPEND:
235       log::info("suspends");
236       aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamSuspended(
237               aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
238       instance->ResetPendingCmd();
239       return;
240     default:
241       log::warn("Invalid state, {}", pending_cmd);
242   }
243 }
244 
GetDecode(bluetooth::common::MessageLoopThread *)245 HfpClientInterface::Decode* HfpClientInterface::GetDecode(
246         bluetooth::common::MessageLoopThread* /*message_loop*/) {
247   if (!is_aidl_support_hfp()) {
248     log::warn("Unsupported HIDL or AIDL version");
249     return nullptr;
250   }
251 
252   if (decode_ == nullptr) {
253     decode_ = new Decode();
254   } else {
255     log::warn("Decode is already acquired");
256     return nullptr;
257   }
258 
259   log::info("decode");
260 
261   HfpDecodingTransport::instance_ =
262           new HfpDecodingTransport(aidl::SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
263   HfpDecodingTransport::software_hal_interface =
264           new aidl::BluetoothAudioSourceClientInterface(HfpDecodingTransport::instance_);
265   if (!HfpDecodingTransport::software_hal_interface->IsValid()) {
266     log::warn("BluetoothAudio HAL for HFP is invalid");
267     delete HfpDecodingTransport::software_hal_interface;
268     HfpDecodingTransport::software_hal_interface = nullptr;
269     delete HfpDecodingTransport::instance_;
270     HfpDecodingTransport::instance_ = nullptr;
271     return nullptr;
272   }
273 
274   HfpDecodingTransport::active_hal_interface = HfpDecodingTransport::software_hal_interface;
275 
276   return decode_;
277 }
278 
ReleaseDecode(HfpClientInterface::Decode * decode)279 bool HfpClientInterface::ReleaseDecode(HfpClientInterface::Decode* decode) {
280   if (decode != decode_) {
281     log::warn("can't release not acquired decode");
282     return false;
283   }
284 
285   log::info("decode");
286   if (get_decode_client_interface()) {
287     decode->Cleanup();
288   }
289 
290   delete decode_;
291   decode_ = nullptr;
292 
293   return true;
294 }
295 
296 // Encoding client implementation
Cleanup()297 void HfpClientInterface::Encode::Cleanup() {
298   log::info("encode");
299   StopSession();
300   if (HfpEncodingTransport::instance_) {
301     delete HfpEncodingTransport::software_hal_interface;
302     HfpEncodingTransport::software_hal_interface = nullptr;
303     delete HfpEncodingTransport::instance_;
304     HfpEncodingTransport::instance_ = nullptr;
305   }
306 }
307 
StartSession()308 void HfpClientInterface::Encode::StartSession() {
309   if (!is_aidl_support_hfp()) {
310     log::warn("Unsupported HIDL or AIDL version");
311     return;
312   }
313   log::info("encode");
314   AudioConfiguration audio_config;
315   audio_config.set<AudioConfiguration::pcmConfig>(get_default_pcm_configuration());
316   if (!get_encode_client_interface()->UpdateAudioConfig(audio_config)) {
317     log::error("cannot update audio config to HAL");
318     return;
319   }
320   get_encode_client_interface()->StartSession();
321 }
322 
StopSession()323 void HfpClientInterface::Encode::StopSession() {
324   if (!is_aidl_support_hfp()) {
325     log::warn("Unsupported HIDL or AIDL version");
326     return;
327   }
328   log::info("encode");
329   get_encode_client_interface()->EndSession();
330   if (get_encode_transport_instance()) {
331     get_encode_transport_instance()->ResetPendingCmd();
332     get_encode_transport_instance()->ResetPresentationPosition();
333   }
334 }
335 
UpdateAudioConfigToHal(const::hfp::offload_config &)336 void HfpClientInterface::Encode::UpdateAudioConfigToHal(
337         const ::hfp::offload_config& /*offload_config*/) {
338   log::warn(
339           "'UpdateAudioConfigToHal(offload_config)' should not be called on "
340           "HfpClientInterface::Encode");
341 }
342 
UpdateAudioConfigToHal(const::hfp::pcm_config & pcm_config)343 void HfpClientInterface::Encode::UpdateAudioConfigToHal(const ::hfp::pcm_config& pcm_config) {
344   if (!is_aidl_support_hfp()) {
345     log::warn("Unsupported HIDL or AIDL version");
346     return;
347   }
348 
349   log::info("encode");
350   if (!get_encode_client_interface()->UpdateAudioConfig(
351               pcm_config_to_hal_audio_config(pcm_config))) {
352     log::error("cannot update audio config to HAL");
353     return;
354   }
355 }
356 
Read(uint8_t * p_buf,uint32_t len)357 size_t HfpClientInterface::Encode::Read(uint8_t* p_buf, uint32_t len) {
358   if (!is_aidl_support_hfp()) {
359     log::warn("Unsupported HIDL or AIDL version");
360     return 0;
361   }
362   log::verbose("encode");
363 
364   auto instance = aidl::hfp::HfpEncodingTransport::instance_;
365   if (instance->IsStreamActive()) {
366     return get_encode_client_interface()->ReadAudioData(p_buf, len);
367   }
368 
369   memset(p_buf, 0x00, len);
370 
371   return len;
372 }
373 
ConfirmStreamingRequest()374 void HfpClientInterface::Encode::ConfirmStreamingRequest() {
375   auto instance = aidl::hfp::HfpEncodingTransport::instance_;
376   auto pending_cmd = instance->GetPendingCmd();
377   switch (pending_cmd) {
378     case aidl::hfp::HFP_CTRL_CMD_NONE:
379       log::warn("no pending start stream request");
380       FALLTHROUGH_INTENDED;
381     case aidl::hfp::HFP_CTRL_CMD_START:
382       aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamStarted(
383               aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
384       instance->ResetPendingCmd();
385       return;
386     default:
387       log::warn("Invalid state, {}", pending_cmd);
388   }
389 }
390 
CancelStreamingRequest()391 void HfpClientInterface::Encode::CancelStreamingRequest() {
392   auto instance = aidl::hfp::HfpEncodingTransport::instance_;
393   auto pending_cmd = instance->GetPendingCmd();
394   switch (pending_cmd) {
395     case aidl::hfp::HFP_CTRL_CMD_START:
396       aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamStarted(
397               aidl::BluetoothAudioCtrlAck::FAILURE);
398       instance->ResetPendingCmd();
399       return;
400     case aidl::hfp::HFP_CTRL_CMD_NONE:
401       log::warn("no pending start stream request");
402       FALLTHROUGH_INTENDED;
403     case aidl::hfp::HFP_CTRL_CMD_SUSPEND:
404       log::info("suspends");
405       aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamSuspended(
406               aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
407       instance->ResetPendingCmd();
408       return;
409     default:
410       log::warn("Invalid state, {}", pending_cmd);
411   }
412 }
413 
GetEncode(bluetooth::common::MessageLoopThread *)414 HfpClientInterface::Encode* HfpClientInterface::GetEncode(
415         bluetooth::common::MessageLoopThread* /*message_loop*/) {
416   if (!is_aidl_support_hfp()) {
417     log::warn("Unsupported HIDL or AIDL version");
418     return nullptr;
419   }
420 
421   if (encode_ == nullptr) {
422     encode_ = new Encode();
423   } else {
424     log::warn("Encoding is already acquired");
425     return nullptr;
426   }
427 
428   log::info("encode");
429 
430   HfpEncodingTransport::instance_ =
431           new HfpEncodingTransport(aidl::SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
432   HfpEncodingTransport::software_hal_interface =
433           new aidl::BluetoothAudioSinkClientInterface(HfpEncodingTransport::instance_);
434   if (!HfpEncodingTransport::software_hal_interface->IsValid()) {
435     log::warn("BluetoothAudio HAL for HFP is invalid");
436     delete HfpEncodingTransport::software_hal_interface;
437     HfpEncodingTransport::software_hal_interface = nullptr;
438     delete HfpEncodingTransport::instance_;
439     HfpEncodingTransport::instance_ = nullptr;
440     return nullptr;
441   }
442 
443   HfpEncodingTransport::active_hal_interface = HfpEncodingTransport::software_hal_interface;
444 
445   return encode_;
446 }
447 
ReleaseEncode(HfpClientInterface::Encode * encode)448 bool HfpClientInterface::ReleaseEncode(HfpClientInterface::Encode* encode) {
449   if (encode != encode_) {
450     log::warn("can't release not acquired encode");
451     return false;
452   }
453 
454   if (get_encode_client_interface()) {
455     encode->Cleanup();
456   }
457 
458   delete encode_;
459   encode_ = nullptr;
460 
461   return true;
462 }
463 
464 // Offload client implementation
465 // Based on HfpEncodingTransport
Cleanup()466 void HfpClientInterface::Offload::Cleanup() {
467   log::info("offload");
468   StopSession();
469   if (HfpEncodingTransport::instance_) {
470     delete HfpEncodingTransport::offloading_hal_interface;
471     HfpEncodingTransport::offloading_hal_interface = nullptr;
472     delete HfpEncodingTransport::instance_;
473     HfpEncodingTransport::instance_ = nullptr;
474   }
475 }
476 
StartSession()477 void HfpClientInterface::Offload::StartSession() {
478   if (!is_aidl_support_hfp()) {
479     log::warn("Unsupported HIDL or AIDL version");
480     return;
481   }
482   log::info("offload");
483   AudioConfiguration audio_config;
484   audio_config.set<AudioConfiguration::hfpConfig>(get_default_hfp_configuration());
485   if (!get_encode_client_interface()->UpdateAudioConfig(audio_config)) {
486     log::error("cannot update audio config to HAL");
487     return;
488   }
489   if (get_encode_client_interface()->StartSession() == 0) {
490     log::info("session started");
491   } else {
492     log::warn("session not started");
493   }
494 }
495 
StopSession()496 void HfpClientInterface::Offload::StopSession() {
497   if (!is_aidl_support_hfp()) {
498     log::warn("Unsupported HIDL or AIDL version");
499     return;
500   }
501   log::info("offload");
502   get_encode_client_interface()->EndSession();
503   if (get_encode_transport_instance()) {
504     get_encode_transport_instance()->ResetPendingCmd();
505     get_encode_transport_instance()->ResetPresentationPosition();
506   }
507 }
508 
UpdateAudioConfigToHal(const::hfp::offload_config & offload_config)509 void HfpClientInterface::Offload::UpdateAudioConfigToHal(
510         const ::hfp::offload_config& offload_config) {
511   if (!is_aidl_support_hfp()) {
512     log::warn("Unsupported HIDL or AIDL version");
513     return;
514   }
515 
516   log::info("offload");
517   get_encode_client_interface()->UpdateAudioConfig(
518           offload_config_to_hal_audio_config(offload_config));
519 }
520 
UpdateAudioConfigToHal(const::hfp::pcm_config &)521 void HfpClientInterface::Offload::UpdateAudioConfigToHal(const ::hfp::pcm_config& /*pcm_config*/) {
522   log::warn(
523           "'UpdateAudioConfigToHal(pcm_config)' should not be called on "
524           "HfpClientInterface::Offload");
525 }
526 
ConfirmStreamingRequest()527 void HfpClientInterface::Offload::ConfirmStreamingRequest() {
528   auto instance = aidl::hfp::HfpEncodingTransport::instance_;
529   auto pending_cmd = instance->GetPendingCmd();
530   switch (pending_cmd) {
531     case aidl::hfp::HFP_CTRL_CMD_START:
532       aidl::hfp::HfpEncodingTransport::offloading_hal_interface->StreamStarted(
533               aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
534       instance->ResetPendingCmd();
535       return;
536     case aidl::hfp::HFP_CTRL_CMD_NONE:
537       log::warn("no pending start stream request");
538       return;
539     default:
540       log::warn("Invalid state, {}", pending_cmd);
541   }
542 }
543 
CancelStreamingRequest()544 void HfpClientInterface::Offload::CancelStreamingRequest() {
545   auto instance = aidl::hfp::HfpEncodingTransport::instance_;
546   auto pending_cmd = instance->GetPendingCmd();
547   switch (pending_cmd) {
548     case aidl::hfp::HFP_CTRL_CMD_START:
549       aidl::hfp::HfpEncodingTransport::offloading_hal_interface->StreamStarted(
550               aidl::BluetoothAudioCtrlAck::FAILURE);
551       instance->ResetPendingCmd();
552       return;
553     case aidl::hfp::HFP_CTRL_CMD_NONE:
554       log::info("no pending start stream request");
555       [[fallthrough]];
556     case aidl::hfp::HFP_CTRL_CMD_SUSPEND:
557       log::info("suspends");
558       aidl::hfp::HfpEncodingTransport::offloading_hal_interface->StreamSuspended(
559               aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
560       instance->ResetPendingCmd();
561       return;
562     default:
563       log::warn("Invalid state, {}", pending_cmd);
564   }
565 }
566 
567 std::unordered_map<tBTA_AG_UUID_CODEC, ::hfp::sco_config>
GetHfpScoConfig()568 HfpClientInterface::Offload::GetHfpScoConfig() {
569   return aidl::hfp::HfpTransport::GetHfpScoConfig(aidl::SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
570 }
571 
GetOffload(bluetooth::common::MessageLoopThread *)572 HfpClientInterface::Offload* HfpClientInterface::GetOffload(
573         bluetooth::common::MessageLoopThread* /*message_loop*/) {
574   if (!is_aidl_support_hfp()) {
575     log::warn("Unsupported HIDL or AIDL version");
576     return nullptr;
577   }
578 
579   if (offload_ == nullptr) {
580     offload_ = new Offload();
581   } else {
582     log::warn("Offload is already acquired");
583     return nullptr;
584   }
585 
586   log::info("offload");
587 
588   // Prepare offload hal interface.
589   if (bta_ag_get_sco_offload_enabled()) {
590     HfpEncodingTransport::instance_ =
591             new HfpEncodingTransport(aidl::SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
592     HfpEncodingTransport::offloading_hal_interface =
593             new aidl::BluetoothAudioSinkClientInterface(HfpEncodingTransport::instance_);
594     if (!HfpEncodingTransport::offloading_hal_interface->IsValid()) {
595       log::fatal("BluetoothAudio HAL for HFP offloading is invalid");
596       delete HfpEncodingTransport::offloading_hal_interface;
597       HfpEncodingTransport::offloading_hal_interface = nullptr;
598       delete HfpEncodingTransport::instance_;
599       HfpEncodingTransport::instance_ = static_cast<HfpEncodingTransport*>(
600               HfpEncodingTransport::software_hal_interface->GetTransportInstance());
601       delete HfpEncodingTransport::software_hal_interface;
602       HfpEncodingTransport::software_hal_interface = nullptr;
603       delete HfpEncodingTransport::instance_;
604       return nullptr;
605     }
606   }
607 
608   HfpEncodingTransport::active_hal_interface = HfpEncodingTransport::offloading_hal_interface;
609 
610   return offload_;
611 }
612 
ReleaseOffload(HfpClientInterface::Offload * offload)613 bool HfpClientInterface::ReleaseOffload(HfpClientInterface::Offload* offload) {
614   if (offload != offload_) {
615     log::warn("can't release not acquired offload");
616     return false;
617   }
618 
619   if (get_encode_client_interface()) {
620     offload->Cleanup();
621   }
622 
623   delete offload_;
624   offload_ = nullptr;
625 
626   return true;
627 }
628 
629 }  // namespace hfp
630 }  // namespace audio
631 }  // namespace bluetooth
632