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 
17 #include "a2dp_encoding.h"
18 #include "client_interface.h"
19 #include "codec_status.h"
20 
21 #include "btif_a2dp_source.h"
22 #include "btif_av.h"
23 #include "btif_av_co.h"
24 #include "btif_hf.h"
25 #include "osi/include/properties.h"
26 
27 namespace {
28 
29 using ::bluetooth::audio::AudioCapabilities;
30 using ::bluetooth::audio::AudioConfiguration;
31 using ::bluetooth::audio::BitsPerSample;
32 using ::bluetooth::audio::BluetoothAudioCtrlAck;
33 using ::bluetooth::audio::ChannelMode;
34 using ::bluetooth::audio::PcmParameters;
35 using ::bluetooth::audio::SampleRate;
36 using ::bluetooth::audio::SessionType;
37 
38 using ::bluetooth::audio::BluetoothAudioClientInterface;
39 using ::bluetooth::audio::codec::A2dpAacToHalConfig;
40 using ::bluetooth::audio::codec::A2dpAptxToHalConfig;
41 using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
42 using ::bluetooth::audio::codec::A2dpCodecToHalChannelMode;
43 using ::bluetooth::audio::codec::A2dpCodecToHalSampleRate;
44 using ::bluetooth::audio::codec::A2dpLdacToHalConfig;
45 using ::bluetooth::audio::codec::A2dpSbcToHalConfig;
46 using ::bluetooth::audio::codec::CodecConfiguration;
47 
48 BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack);
49 
50 // Provide call-in APIs for the Bluetooth Audio HAL
51 class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance {
52  public:
A2dpTransport(SessionType sessionType)53   A2dpTransport(SessionType sessionType)
54       : IBluetoothTransportInstance(sessionType, {}),
55         total_bytes_read_(0),
56         data_position_({}) {
57     a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
58     remote_delay_report_ = 0;
59   }
60 
StartRequest()61   BluetoothAudioCtrlAck StartRequest() override {
62     // Check if a previous request is not finished
63     if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
64       LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
65       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
66     } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
67       LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
68       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
69     }
70 
71     // Don't send START request to stack while we are in a call
72     if (!bluetooth::headset::IsCallIdle()) {
73       LOG(ERROR) << __func__ << ": call state is busy";
74       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE);
75     }
76 
77     if (btif_av_stream_started_ready()) {
78       // Already started, ACK back immediately.
79       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
80     }
81     if (btif_av_stream_ready()) {
82       /*
83        * Post start event and wait for audio path to open.
84        * If we are the source, the ACK will be sent after the start
85        * procedure is completed, othewise send it now.
86        */
87       a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
88       btif_av_stream_start();
89       if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
90         LOG(INFO) << __func__ << ": accepted";
91         return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
92       }
93       a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
94       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
95     }
96     LOG(ERROR) << __func__ << ": AV stream is not ready to start";
97     return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
98   }
99 
SuspendRequest()100   BluetoothAudioCtrlAck SuspendRequest() override {
101     // Previous request is not finished
102     if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
103       LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_SUSPEND in progress";
104       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
105     } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
106       LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
107       return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
108     }
109     // Local suspend
110     if (btif_av_stream_started_ready()) {
111       LOG(INFO) << __func__ << ": accepted";
112       a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
113       btif_av_stream_suspend();
114       return BluetoothAudioCtrlAck::PENDING;
115     }
116     /* If we are not in started state, just ack back ok and let
117      * audioflinger close the channel. This can happen if we are
118      * remotely suspended, clear REMOTE SUSPEND flag.
119      */
120     btif_av_clear_remote_suspend_flag();
121     return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
122   }
123 
StopRequest()124   void StopRequest() override {
125     if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
126         !btif_av_stream_started_ready()) {
127       return;
128     }
129     LOG(INFO) << __func__ << ": handling";
130     a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
131     btif_av_stream_stop(RawAddress::kEmpty);
132   }
133 
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)134   bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
135                                uint64_t* total_bytes_read,
136                                timespec* data_position) override {
137     *remote_delay_report_ns = remote_delay_report_ * 100000u;
138     *total_bytes_read = total_bytes_read_;
139     *data_position = data_position_;
140     VLOG(2) << __func__ << ": delay=" << remote_delay_report_
141             << "/10ms, data=" << total_bytes_read_
142             << " byte(s), timestamp=" << data_position_.tv_sec << "."
143             << data_position_.tv_nsec << "s";
144     return true;
145   }
146 
MetadataChanged(const source_metadata_t & source_metadata)147   void MetadataChanged(const source_metadata_t& source_metadata) override {
148     auto track_count = source_metadata.track_count;
149     auto tracks = source_metadata.tracks;
150     VLOG(1) << __func__ << ": " << track_count << " track(s) received";
151     while (track_count) {
152       VLOG(2) << __func__ << ": usage=" << tracks->usage
153               << ", content_type=" << tracks->content_type
154               << ", gain=" << tracks->gain;
155       --track_count;
156       ++tracks;
157     }
158   }
159 
GetPendingCmd() const160   tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
161 
ResetPendingCmd()162   void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
163 
ResetPresentationPosition()164   void ResetPresentationPosition() override {
165     remote_delay_report_ = 0;
166     total_bytes_read_ = 0;
167     data_position_ = {};
168   }
169 
LogBytesRead(size_t bytes_read)170   void LogBytesRead(size_t bytes_read) override {
171     if (bytes_read != 0) {
172       total_bytes_read_ += bytes_read;
173       clock_gettime(CLOCK_MONOTONIC, &data_position_);
174     }
175   }
176 
177   // delay reports from AVDTP is based on 1/10 ms (100us)
SetRemoteDelay(uint16_t delay_report)178   void SetRemoteDelay(uint16_t delay_report) {
179     remote_delay_report_ = delay_report;
180   }
181 
182  private:
183   static tA2DP_CTRL_CMD a2dp_pending_cmd_;
184   static uint16_t remote_delay_report_;
185   uint64_t total_bytes_read_;
186   timespec data_position_;
187 };
188 
189 tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
190 uint16_t A2dpTransport::remote_delay_report_ = 0;
191 
192 // Common interface to call-out into Bluetooth Audio HAL
193 BluetoothAudioClientInterface* software_hal_interface = nullptr;
194 BluetoothAudioClientInterface* offloading_hal_interface = nullptr;
195 BluetoothAudioClientInterface* active_hal_interface = nullptr;
196 
197 // Save the value if the remote reports its delay before this interface is
198 // initialized
199 uint16_t remote_delay = 0;
200 
201 bool btaudio_a2dp_disabled = false;
202 bool is_configured = false;
203 
a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack)204 BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
205   switch (ack) {
206     case A2DP_CTRL_ACK_SUCCESS:
207       return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
208     case A2DP_CTRL_ACK_PENDING:
209       return BluetoothAudioCtrlAck::PENDING;
210     case A2DP_CTRL_ACK_INCALL_FAILURE:
211       return BluetoothAudioCtrlAck::FAILURE_BUSY;
212     case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
213       return BluetoothAudioCtrlAck::FAILURE_DISCONNECTING;
214     case A2DP_CTRL_ACK_UNSUPPORTED: /* Offloading but resource failure */
215       return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
216     case A2DP_CTRL_ACK_FAILURE:
217       return BluetoothAudioCtrlAck::FAILURE;
218     default:
219       return BluetoothAudioCtrlAck::FAILURE;
220   }
221 }
222 
a2dp_get_selected_hal_codec_config(CodecConfiguration * codec_config)223 bool a2dp_get_selected_hal_codec_config(CodecConfiguration* codec_config) {
224   A2dpCodecConfig* a2dp_config = bta_av_get_a2dp_current_codec();
225   if (a2dp_config == nullptr) {
226     LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
227     *codec_config = ::bluetooth::audio::codec::kInvalidCodecConfiguration;
228     return false;
229   }
230   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
231   switch (current_codec.codec_type) {
232     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
233       [[fallthrough]];
234     case BTAV_A2DP_CODEC_INDEX_SINK_SBC: {
235       if (!A2dpSbcToHalConfig(codec_config, a2dp_config)) {
236         return false;
237       }
238       break;
239     }
240     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
241       [[fallthrough]];
242     case BTAV_A2DP_CODEC_INDEX_SINK_AAC: {
243       if (!A2dpAacToHalConfig(codec_config, a2dp_config)) {
244         return false;
245       }
246       break;
247     }
248     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
249       [[fallthrough]];
250     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: {
251       if (!A2dpAptxToHalConfig(codec_config, a2dp_config)) {
252         return false;
253       }
254       break;
255     }
256     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: {
257       if (!A2dpLdacToHalConfig(codec_config, a2dp_config)) {
258         return false;
259       }
260       break;
261     }
262     case BTAV_A2DP_CODEC_INDEX_MAX:
263       [[fallthrough]];
264     default:
265       LOG(ERROR) << __func__
266                  << ": Unknown codec_type=" << current_codec.codec_type;
267       *codec_config = ::bluetooth::audio::codec::kInvalidCodecConfiguration;
268       return false;
269   }
270   codec_config->encodedAudioBitrate = a2dp_config->getTrackBitRate();
271   // Obtain the MTU
272   RawAddress peer_addr = btif_av_source_active_peer();
273   tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
274   bta_av_co_get_peer_params(peer_addr, &peer_param);
275   int effectiveMtu = a2dp_config->getEffectiveMtu();
276   if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
277     codec_config->peerMtu = effectiveMtu;
278   } else {
279     codec_config->peerMtu = peer_param.peer_mtu;
280   }
281   LOG(INFO) << __func__ << ": CodecConfiguration=" << toString(*codec_config);
282   return true;
283 }
284 
a2dp_get_selected_hal_pcm_config(PcmParameters * pcm_config)285 bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
286   if (pcm_config == nullptr) return false;
287   A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
288   if (a2dp_codec_configs == nullptr) {
289     LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
290     *pcm_config = ::bluetooth::audio::BluetoothAudioClientInterface::
291         kInvalidPcmConfiguration;
292     return false;
293   }
294 
295   btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
296   pcm_config->sampleRate = A2dpCodecToHalSampleRate(current_codec);
297   pcm_config->bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
298   pcm_config->channelMode = A2dpCodecToHalChannelMode(current_codec);
299   return (pcm_config->sampleRate != SampleRate::RATE_UNKNOWN &&
300           pcm_config->bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
301           pcm_config->channelMode != ChannelMode::UNKNOWN);
302 }
303 
304 // Checking if new bluetooth_audio is supported
is_hal_2_0_force_disabled()305 bool is_hal_2_0_force_disabled() {
306   if (!is_configured) {
307     btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
308     is_configured = true;
309   }
310   return btaudio_a2dp_disabled;
311 }
312 }  // namespace
313 
314 namespace bluetooth {
315 namespace audio {
316 namespace a2dp {
317 
update_codec_offloading_capabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference)318 bool update_codec_offloading_capabilities(
319     const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
320   return ::bluetooth::audio::codec::UpdateOffloadingCapabilities(
321       framework_preference);
322 }
323 
324 // Checking if new bluetooth_audio is enabled
is_hal_2_0_enabled()325 bool is_hal_2_0_enabled() { return active_hal_interface != nullptr; }
326 
327 // Check if new bluetooth_audio is running with offloading encoders
is_hal_2_0_offloading()328 bool is_hal_2_0_offloading() {
329   if (!is_hal_2_0_enabled()) {
330     return false;
331   }
332   return active_hal_interface->GetTransportInstance()->GetSessionType() ==
333          SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
334 }
335 
336 // Initialize BluetoothAudio HAL: openProvider
init(bluetooth::common::MessageLoopThread * message_loop)337 bool init(bluetooth::common::MessageLoopThread* message_loop) {
338   LOG(INFO) << __func__;
339 
340   if (is_hal_2_0_force_disabled()) {
341     LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
342     return false;
343   }
344 
345   auto a2dp_sink =
346       new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
347   software_hal_interface = new bluetooth::audio::BluetoothAudioClientInterface(
348       a2dp_sink, message_loop);
349   if (!software_hal_interface->IsValid()) {
350     LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!";
351     delete software_hal_interface;
352     software_hal_interface = nullptr;
353     delete a2dp_sink;
354     return false;
355   }
356 
357   if (btif_av_is_a2dp_offload_enabled()) {
358     a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
359     offloading_hal_interface =
360         new bluetooth::audio::BluetoothAudioClientInterface(a2dp_sink,
361                                                             message_loop);
362     if (!offloading_hal_interface->IsValid()) {
363       LOG(FATAL) << __func__
364                  << ": BluetoothAudio HAL for A2DP offloading is invalid?!";
365       delete offloading_hal_interface;
366       offloading_hal_interface = nullptr;
367       delete a2dp_sink;
368       a2dp_sink = static_cast<A2dpTransport*>(
369           software_hal_interface->GetTransportInstance());
370       delete software_hal_interface;
371       software_hal_interface = nullptr;
372       delete a2dp_sink;
373       return false;
374     }
375   }
376 
377   active_hal_interface =
378       (offloading_hal_interface != nullptr ? offloading_hal_interface
379                                            : software_hal_interface);
380 
381   if (remote_delay != 0) {
382     LOG(INFO) << __func__ << ": restore DELAY "
383               << static_cast<float>(remote_delay / 10.0) << " ms";
384     static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
385         ->SetRemoteDelay(remote_delay);
386     remote_delay = 0;
387   }
388   return true;
389 }
390 
391 // Clean up BluetoothAudio HAL
cleanup()392 void cleanup() {
393   if (!is_hal_2_0_enabled()) return;
394   end_session();
395 
396   auto a2dp_sink = active_hal_interface->GetTransportInstance();
397   static_cast<A2dpTransport*>(a2dp_sink)->ResetPendingCmd();
398   static_cast<A2dpTransport*>(a2dp_sink)->ResetPresentationPosition();
399   active_hal_interface = nullptr;
400 
401   a2dp_sink = software_hal_interface->GetTransportInstance();
402   delete software_hal_interface;
403   software_hal_interface = nullptr;
404   delete a2dp_sink;
405   if (offloading_hal_interface != nullptr) {
406     a2dp_sink = offloading_hal_interface->GetTransportInstance();
407     delete offloading_hal_interface;
408     offloading_hal_interface = nullptr;
409     delete a2dp_sink;
410   }
411 
412   remote_delay = 0;
413 }
414 
415 // Set up the codec into BluetoothAudio HAL
setup_codec()416 bool setup_codec() {
417   if (!is_hal_2_0_enabled()) {
418     LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
419     return false;
420   }
421   CodecConfiguration codec_config{};
422   if (!a2dp_get_selected_hal_codec_config(&codec_config)) {
423     LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration";
424     return false;
425   }
426   bool should_codec_offloading =
427       bluetooth::audio::codec::IsCodecOffloadingEnabled(codec_config);
428   if (should_codec_offloading && !is_hal_2_0_offloading()) {
429     LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Hardware";
430     end_session();
431     active_hal_interface = offloading_hal_interface;
432   } else if (!should_codec_offloading && is_hal_2_0_offloading()) {
433     LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Software";
434     end_session();
435     active_hal_interface = software_hal_interface;
436   }
437 
438   AudioConfiguration audio_config{};
439   if (active_hal_interface->GetTransportInstance()->GetSessionType() ==
440       SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
441     audio_config.codecConfig(codec_config);
442   } else {
443     PcmParameters pcm_config{};
444     if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) {
445       LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration";
446       return false;
447     }
448     audio_config.pcmConfig(pcm_config);
449   }
450   return active_hal_interface->UpdateAudioConfig(audio_config);
451 }
452 
start_session()453 void start_session() {
454   if (!is_hal_2_0_enabled()) {
455     LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
456     return;
457   }
458   active_hal_interface->StartSession();
459 }
460 
end_session()461 void end_session() {
462   if (!is_hal_2_0_enabled()) {
463     LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
464     return;
465   }
466   active_hal_interface->EndSession();
467   static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
468       ->ResetPresentationPosition();
469 }
470 
ack_stream_started(const tA2DP_CTRL_ACK & ack)471 void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
472   auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
473   LOG(INFO) << __func__ << ": result=" << ctrl_ack;
474   auto a2dp_sink =
475       static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
476   auto pending_cmd = a2dp_sink->GetPendingCmd();
477   if (pending_cmd == A2DP_CTRL_CMD_START) {
478     active_hal_interface->StreamStarted(ctrl_ack);
479   } else {
480     LOG(WARNING) << __func__ << ": pending=" << pending_cmd
481                  << " ignore result=" << ctrl_ack;
482     return;
483   }
484   if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
485     a2dp_sink->ResetPendingCmd();
486   }
487 }
488 
ack_stream_suspended(const tA2DP_CTRL_ACK & ack)489 void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
490   auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
491   LOG(INFO) << __func__ << ": result=" << ctrl_ack;
492   auto a2dp_sink =
493       static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
494   auto pending_cmd = a2dp_sink->GetPendingCmd();
495   if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) {
496     active_hal_interface->StreamSuspended(ctrl_ack);
497   } else if (pending_cmd == A2DP_CTRL_CMD_STOP) {
498     LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack;
499   } else {
500     LOG(WARNING) << __func__ << ": pending=" << pending_cmd
501                  << " ignore result=" << ctrl_ack;
502     return;
503   }
504   if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
505     a2dp_sink->ResetPendingCmd();
506   }
507 }
508 
509 // Read from the FMQ of BluetoothAudio HAL
read(uint8_t * p_buf,uint32_t len)510 size_t read(uint8_t* p_buf, uint32_t len) {
511   if (!is_hal_2_0_enabled()) {
512     LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
513     return 0;
514   } else if (is_hal_2_0_offloading()) {
515     LOG(ERROR) << __func__ << ": session_type="
516                << toString(active_hal_interface->GetTransportInstance()
517                                ->GetSessionType())
518                << " is not A2DP_SOFTWARE_ENCODING_DATAPATH";
519     return 0;
520   }
521   return active_hal_interface->ReadAudioData(p_buf, len);
522 }
523 
524 // Update A2DP delay report to BluetoothAudio HAL
set_remote_delay(uint16_t delay_report)525 void set_remote_delay(uint16_t delay_report) {
526   if (!is_hal_2_0_enabled()) {
527     LOG(INFO) << __func__ << ":  not ready for DelayReport "
528               << static_cast<float>(delay_report / 10.0) << " ms";
529     remote_delay = delay_report;
530     return;
531   }
532   VLOG(1) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0)
533           << " ms";
534   static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
535       ->SetRemoteDelay(delay_report);
536 }
537 
538 }  // namespace a2dp
539 }  // namespace audio
540 }  // namespace bluetooth
541