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