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