• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <map>
17 #include <hdf_log.h>
18 #include <atomic>
19 #include "audio_internal.h"
20 #include "i_bluetooth_a2dp_src.h"
21 #include "i_bluetooth_host.h"
22 #include "bluetooth_a2dp_src_observer.h"
23 #include "bluetooth_def.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #include "audio_bluetooth_manager.h"
27 
28 #ifdef A2DP_HDI_SERVICE
29 #include "bluetooth_audio_device.h"
30 #endif
31 
32 #define HDF_LOG_TAG BTAudioBluetoothManager
33 
34 namespace OHOS {
35 namespace Bluetooth {
36 using namespace OHOS::bluetooth;
37 
38 #ifdef A2DP_HDI_SERVICE
39 using namespace OHOS::bluetooth::audio;
40 static const char *g_bluetoothAudioDeviceSoPath = HDF_LIBRARY_FULL_PATH("libbluetooth_audio_session");
41 static void *g_ptrAudioDeviceHandle = NULL;
42 std::atomic_bool g_allowAudioStart = true;
43 
44 SetUpFunc setUpFunc;
45 TearDownFunc tearDownFunc;
46 GetStateFunc getStateFunc;
47 StartPlayingFunc startPlayingFunc;
48 SuspendPlayingFunc suspendPlayingFunc;
49 StopPlayingFunc stopPlayingFunc;
50 WriteFrameFunc writeFrameFunc;
51 GetLatencyFunc getLatencyFunc;
52 
53 SetUpFunc fastSetUpFunc;
54 TearDownFunc fastTearDownFunc;
55 GetStateFunc fastGetStateFunc;
56 StartPlayingFunc fastStartPlayingFunc;
57 SuspendPlayingFunc fastSuspendPlayingFunc;
58 StopPlayingFunc fastStopPlayingFunc;
59 ReqMmapBufferFunc fastReqMmapBufferFunc;
60 ReadMmapPositionFunc fastReadMmapPositionFunc;
61 GetLatencyFunc fastGetLatencyFunc;
62 GetRealStateFunc getRealStateFunc;
63 GetRenderMixerStateFunc getRenderMixerStateFunc;
64 
65 SetUpFunc setUpCaptureFunc;
66 TearDownFunc tearDownCaptureFunc;
67 GetStateFunc getCaptureStateFunc;
68 StartCaptureFunc startCaptureFunc;
69 SuspendPlayingFunc suspendCaptureFunc;
70 StopPlayingFunc stopCaptureFunc;
71 ReadFrameFunc readFrameFunc;
72 #endif
73 
74 sptr<IBluetoothA2dpSrc> g_proxy_ = nullptr;
75 static sptr<BluetoothA2dpSrcObserver> g_btA2dpSrcObserverCallbacks = nullptr;
76 int g_playState = A2DP_NOT_PLAYING;
77 std::map<int, std::string> g_playdevices {};
78 std::mutex g_playStateMutex;
79 
AudioOnConnectionStateChanged(const RawAddress & device,int state,int cause)80 static void AudioOnConnectionStateChanged(const RawAddress &device, int state, int cause)
81 {
82     HDF_LOGI("%{public}s, state:%{public}d", __func__, state);
83     (void) state;
84     (void) cause;
85 }
86 
AudioOnPlayingStatusChanged(const RawAddress & device,int playingState,int error)87 static void AudioOnPlayingStatusChanged(const RawAddress &device, int playingState, int error)
88 {
89     HDF_LOGI("%{public}s, playingState:%{public}d", __func__, playingState);
90     std::lock_guard<std::mutex> lock(g_playStateMutex);
91     std::string addr = device.GetAddress();
92     if (playingState) {
93         for (const auto &it : g_playdevices) {
94             if (strcmp(it.second.c_str(), device.GetAddress().c_str()) == 0) {
95                 return;
96             }
97         }
98         g_playdevices.insert(std::make_pair(playingState, addr));
99         g_playState = playingState;
100     } else {
101         std::map<int, std::string>::iterator it;
102         for (it = g_playdevices.begin(); it != g_playdevices.end(); it++) {
103             if (strcmp(it->second.c_str(), device.GetAddress().c_str()) == 0) {
104                 g_playdevices.erase(it);
105                 break;
106             }
107         }
108         if (g_playdevices.empty()) {
109             g_playState = playingState;
110         }
111     }
112     (void) error;
113 }
114 
AudioOnConfigurationChanged(const RawAddress & device,const BluetoothA2dpCodecInfo & info,int error)115 static void AudioOnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error)
116 {
117     (void) device;
118     (void) info;
119     (void) error;
120 }
121 
AudioOnMediaStackChanged(const RawAddress & device,int action)122 static void AudioOnMediaStackChanged(const RawAddress &device, int action)
123 {
124     (void) device;
125     (void) action;
126 }
127 
128 
129 static BtA2dpAudioCallback g_hdiCallbacks = {
130     .OnConnectionStateChanged = AudioOnConnectionStateChanged,
131     .OnPlayingStatusChanged = AudioOnPlayingStatusChanged,
132     .OnConfigurationChanged =  AudioOnConfigurationChanged,
133     .OnMediaStackChanged = AudioOnMediaStackChanged,
134 };
135 
GetPlayingState()136 int GetPlayingState()
137 {
138     HDF_LOGI("%{public}s: state:%{public}d", __func__, g_playState);
139     return g_playState;
140 }
141 
GetProxy()142 void GetProxy()
143 {
144     HDF_LOGI("%{public}s start", __func__);
145     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
146     if (!samgr) {
147         HDF_LOGE("%{public}s: error: no samgr", __func__);
148         return;
149     }
150 
151     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
152     if (!hostRemote) {
153         HDF_LOGE("%{public}s: failed: no hostRemote", __func__);
154         return;
155     }
156 
157     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
158     if (!hostProxy) {
159         HDF_LOGE("%{public}s: error: host no proxy", __func__);
160         return;
161     }
162 
163     sptr<IRemoteObject> remote = hostProxy->GetProfile("A2dpSrcServer");
164     if (!remote) {
165         HDF_LOGE("%{public}s: error: no remote", __func__);
166         return;
167     }
168 
169     g_proxy_ = iface_cast<IBluetoothA2dpSrc>(remote);
170     if (!g_proxy_) {
171         HDF_LOGE("%{public}s: error: no proxy", __func__);
172         return;
173     }
174 }
175 
RegisterObserver()176 void RegisterObserver()
177 {
178     HDF_LOGI("%{public}s", __func__);
179     g_btA2dpSrcObserverCallbacks = new (std::nothrow) BluetoothA2dpSrcObserver(&g_hdiCallbacks);
180     if (!g_btA2dpSrcObserverCallbacks) {
181         HDF_LOGE("%{public}s: g_btA2dpSrcObserverCallbacks is null", __func__);
182         return;
183     }
184     if (!g_proxy_) {
185         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
186         return;
187     }
188     g_proxy_->RegisterObserver(g_btA2dpSrcObserverCallbacks);
189 }
190 
DeRegisterObserver()191 void DeRegisterObserver()
192 {
193     HDF_LOGI("%{public}s", __func__);
194     if (!g_proxy_) {
195         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
196         return;
197     }
198     g_proxy_->DeregisterObserver(g_btA2dpSrcObserverCallbacks);
199 }
200 
201 #ifdef A2DP_HDI_SERVICE
202 #define GET_SYM_ERRPR_RET(handle, funcType, funcPtr, funcStr)       \
203     do {                                                            \
204         funcPtr = (funcType)dlsym(handle, funcStr);                 \
205         if (funcPtr == nullptr) {                                   \
206             HDF_LOGE("%{public}s: lib so func not found", funcStr); \
207             return false;                                           \
208         }                                                           \
209     } while (0)
210 
InitAudioDeviceSoHandle(const char * path)211 static bool InitAudioDeviceSoHandle(const char *path)
212 {
213     if (path == NULL) {
214         HDF_LOGE("%{public}s: path is NULL", __func__);
215         return false;
216     }
217     char pathBuf[PATH_MAX] = {'\0'};
218     if (realpath(path, pathBuf) == NULL) {
219         return false;
220     }
221     if (g_ptrAudioDeviceHandle == NULL) {
222         g_ptrAudioDeviceHandle = dlopen(pathBuf, RTLD_LAZY);
223         if (g_ptrAudioDeviceHandle == NULL) {
224             HDF_LOGE("%{public}s: open lib so fail, reason:%{public}s ", __func__, dlerror());
225             return false;
226         }
227         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, setUpFunc, "SetUp");
228         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, tearDownFunc, "TearDown");
229         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, getStateFunc, "GetState");
230         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartPlayingFunc, startPlayingFunc, "StartPlaying");
231         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, suspendPlayingFunc, "SuspendPlaying");
232         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, stopPlayingFunc, "StopPlaying");
233         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, WriteFrameFunc, writeFrameFunc, "WriteFrame");
234         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetLatencyFunc, getLatencyFunc, "GetLatency");
235 
236         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, fastSetUpFunc, "FastSetUp");
237         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, fastTearDownFunc, "FastTearDown");
238         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, fastGetStateFunc, "FastGetState");
239         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartPlayingFunc, fastStartPlayingFunc, "FastStartPlaying");
240         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, fastSuspendPlayingFunc, "FastSuspendPlaying");
241         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, fastStopPlayingFunc, "FastStopPlaying");
242         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, ReqMmapBufferFunc, fastReqMmapBufferFunc, "FastReqMmapBuffer");
243         GET_SYM_ERRPR_RET(
244             g_ptrAudioDeviceHandle, ReadMmapPositionFunc, fastReadMmapPositionFunc, "FastReadMmapPosition");
245         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetLatencyFunc, fastGetLatencyFunc, "FastGetLatency");
246         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetRealStateFunc, getRealStateFunc, "GetRealState");
247         GET_SYM_ERRPR_RET(
248             g_ptrAudioDeviceHandle, GetRenderMixerStateFunc, getRenderMixerStateFunc, "GetRenderMixerState");
249 
250         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, setUpCaptureFunc, "SetUpCapture");
251         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, tearDownCaptureFunc, "TearDownCapture");
252         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, getCaptureStateFunc, "GetCaptureState");
253         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartCaptureFunc, startCaptureFunc, "StartCapture");
254         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, suspendCaptureFunc, "SuspendCapture");
255         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, stopCaptureFunc, "StopCapture");
256         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, ReadFrameFunc, readFrameFunc, "ReadFrame");
257     }
258     return true;
259 }
260 
SetUp()261 bool SetUp()
262 {
263     bool ret = false;
264     ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
265     if (ret == true) {
266         ret = setUpFunc();
267     }
268     if (ret == false) {
269         HDF_LOGE("%{public}s failed!", __func__);
270     }
271     return ret;
272 }
273 
SetUpCapture()274 bool SetUpCapture()
275 {
276     bool ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
277     if (ret) {
278         ret = setUpCaptureFunc();
279     }
280     if (!ret) {
281         HDF_LOGE("%{public}s failed!", __func__);
282     }
283     return ret;
284 }
285 
TearDown()286 void TearDown()
287 {
288     tearDownFunc();
289 }
290 
TearDownCapture()291 void TearDownCapture()
292 {
293     tearDownCaptureFunc();
294 }
295 
FastSetUp()296 bool FastSetUp()
297 {
298     bool ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
299     if (ret) {
300         ret = fastSetUpFunc();
301     }
302     if (!ret) {
303         HDF_LOGE("%{public}s failed", __func__);
304     }
305     return ret;
306 }
307 
FastTearDown()308 void FastTearDown()
309 {
310     fastTearDownFunc();
311 }
312 
FastStartPlaying(uint32_t sampleRate,uint32_t channelCount,uint32_t format)313 int FastStartPlaying(uint32_t sampleRate, uint32_t channelCount, uint32_t format)
314 {
315     BTAudioStreamState state = fastGetStateFunc();
316     if (!g_allowAudioStart.load()) {
317         HDF_LOGE("not allow to start fast render, state=%{public}hhu", state);
318         return HDF_FAILURE;
319     } else if (state != BTAudioStreamState::STARTED) {
320         HDF_LOGI("%{public}s, state=%{public}hhu", __func__, state);
321         if (!fastStartPlayingFunc(sampleRate, channelCount, format)) {
322             HDF_LOGE("%{public}s, fail to startPlaying", __func__);
323             return HDF_FAILURE;
324         }
325     }
326     return HDF_SUCCESS;
327 }
328 
FastSuspendPlayingFromParam()329 int FastSuspendPlayingFromParam()
330 {
331     int ret = 0;
332     RenderMixerState renderState = getRenderMixerStateFunc();
333     if (!g_allowAudioStart.load()) {
334         if (renderState == RenderMixerState::INITED || renderState == RenderMixerState::NORMAL_ON_MIX_STOP) {
335             HDF_LOGE("fast render is already stopping or stopped");
336             return ret;
337         }
338     }
339 
340     BTAudioStreamState state = fastGetStateFunc();
341     BTAudioStreamState realState = getRealStateFunc();
342     g_allowAudioStart = false;
343     if (state == BTAudioStreamState::STARTED) {
344         HDF_LOGI("%{public}s", __func__);
345         ret = (fastSuspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
346     } else if (realState == BTAudioStreamState::STARTING && renderState == RenderMixerState::FAST_STARTED) {
347         HDF_LOGI("%{public}s fast render starting, so stopPlaying", __func__);
348         ret = (fastStopPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
349     } else {
350         HDF_LOGE("%{public}s, state=%{public}hhu is bad state, realState=%{public}hhu, renderState=%{public}hhu",
351             __func__, state, realState, renderState);
352     }
353     return ret;
354 }
355 
FastSuspendPlaying()356 int FastSuspendPlaying()
357 {
358     int ret = 0;
359     BTAudioStreamState state = fastGetStateFunc();
360     if (state == BTAudioStreamState::STARTED) {
361         ret = (fastSuspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
362     } else {
363         HDF_LOGE("%{public}s, state=%{public}hhu is bad state", __func__, state);
364     }
365     return ret;
366 }
367 
FastStopPlaying()368 int FastStopPlaying()
369 {
370     BTAudioStreamState state = fastGetStateFunc();
371     HDF_LOGI("%{public}s, state=%{public}hhu", __func__, state);
372     if (state != BTAudioStreamState::INVALID) {
373         fastStopPlayingFunc();
374     }
375     return HDF_SUCCESS;
376 }
377 
FastReqMmapBuffer(int32_t ashmemLength)378 int FastReqMmapBuffer(int32_t ashmemLength)
379 {
380     return fastReqMmapBufferFunc(ashmemLength);
381 }
382 
FastReadMmapPosition(int64_t & sec,int64_t & nSec,uint64_t & frames)383 void FastReadMmapPosition(int64_t &sec, int64_t &nSec, uint64_t &frames)
384 {
385     fastReadMmapPositionFunc(sec, nSec, frames);
386 }
387 
FastGetLatency(uint32_t & latency)388 int FastGetLatency(uint32_t &latency)
389 {
390     return (fastGetLatencyFunc(latency) ? HDF_SUCCESS : HDF_FAILURE);
391 }
392 
SuspendPlayingFromParam()393 int SuspendPlayingFromParam()
394 {
395     int retVal = 0;
396     RenderMixerState renderState = getRenderMixerStateFunc();
397     if (!g_allowAudioStart.load()) {
398         if (renderState == RenderMixerState::INITED || renderState == RenderMixerState::FAST_ON_MIX_STOP) {
399             HDF_LOGE("normal render is already stopping or stopped");
400             return retVal;
401         }
402     }
403 
404     BTAudioStreamState state = getStateFunc();
405     BTAudioStreamState realState = getRealStateFunc();
406     g_allowAudioStart = false;
407     if (state == BTAudioStreamState::STARTED) {
408         HDF_LOGI("%{public}s", __func__);
409         retVal = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
410     } else if (realState == BTAudioStreamState::STARTING && renderState == RenderMixerState::INITED) {
411         HDF_LOGI("%{public}s normal render starting, so stopPlaying", __func__);
412         retVal = (stopPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
413     } else {
414         HDF_LOGE("%{public}s, state=%{public}hhu is bad state, realState=%{public}hhu, renderState=%{public}hhu",
415             __func__, state, realState, renderState);
416     }
417     return retVal;
418 }
419 
UnBlockStart()420 void UnBlockStart()
421 {
422     g_allowAudioStart = true;
423 }
424 
StartCapture()425 int StartCapture()
426 {
427     BTAudioStreamState state = getCaptureStateFunc();
428     if (state != BTAudioStreamState::STARTED) {
429         HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
430         if (!startCaptureFunc()) {
431             HDF_LOGE("%{public}s: fail to startPlaying", __func__);
432             return HDF_FAILURE;
433         }
434     }
435     return HDF_SUCCESS;
436 }
437 
SuspendCapture()438 int SuspendCapture()
439 {
440     int ret = 0;
441     BTAudioStreamState state = getCaptureStateFunc();
442     if (state == BTAudioStreamState::STARTED) {
443         ret = suspendCaptureFunc() ? HDF_SUCCESS : HDF_FAILURE;
444     } else {
445         HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
446     }
447     return ret;
448 }
449 
StopCapture()450 int StopCapture()
451 {
452     BTAudioStreamState state = getCaptureStateFunc();
453     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
454     if (state != BTAudioStreamState::INVALID) {
455         stopCaptureFunc();
456     }
457     return HDF_SUCCESS;
458 }
459 
ReadFrame(uint8_t * data,uint64_t size)460 int ReadFrame(uint8_t *data, uint64_t size)
461 {
462     HDF_LOGD("%{public}s", __func__);
463     return readFrameFunc(data, size);
464 }
465 
466 #endif
467 
WriteFrame(const uint8_t * data,uint32_t size,const HDI::Audio_Bluetooth::AudioSampleAttributes * attrs)468 int WriteFrame(const uint8_t *data, uint32_t size, const HDI::Audio_Bluetooth::AudioSampleAttributes *attrs)
469 {
470     HDF_LOGD("%{public}s", __func__);
471 #ifdef A2DP_HDI_SERVICE
472     BTAudioStreamState state = getStateFunc();
473     if (!g_allowAudioStart.load()) {
474         HDF_LOGE("not allow to start normal render, state=%{public}hhu", state);
475         return HDF_FAILURE;
476     } else if (state != BTAudioStreamState::STARTED) {
477         HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
478         if (!startPlayingFunc(attrs->sampleRate, attrs->channelCount, static_cast<uint32_t>(attrs->format))) {
479             HDF_LOGE("%{public}s: fail to startPlaying", __func__);
480             return HDF_FAILURE;
481         }
482     }
483     return writeFrameFunc(data, size);
484 #else
485     if (!g_proxy_) {
486         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
487         return RET_BAD_STATUS;
488     }
489     if (g_playState == A2DP_NOT_PLAYING) {
490         HDF_LOGE("%{public}s: playState is not Streaming", __func__);
491         return RET_BAD_STATUS;
492     }
493     return g_proxy_->WriteFrame(data, size);
494 #endif
495 }
496 
StartPlaying()497 int StartPlaying()
498 {
499     HDF_LOGI("%{public}s", __func__);
500 #ifdef A2DP_HDI_SERVICE
501     return HDF_SUCCESS;
502 #else
503     if (!g_proxy_) {
504         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
505         return RET_BAD_STATUS;
506     }
507     return g_proxy_->StartPlaying(g_proxy_->GetActiveSinkDevice());
508 #endif
509 }
510 
SuspendPlaying()511 int SuspendPlaying()
512 {
513 #ifdef A2DP_HDI_SERVICE
514     int retval = 0;
515     BTAudioStreamState state = getStateFunc();
516     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
517     if (state == BTAudioStreamState::STARTED) {
518         retval = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
519     } else {
520         HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
521     }
522     return retval;
523 #else
524     HDF_LOGI("%{public}s", __func__);
525     if (!g_proxy_) {
526         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
527         return RET_BAD_STATUS;
528     }
529     return g_proxy_->SuspendPlaying(g_proxy_->GetActiveSinkDevice());
530 #endif
531 }
532 
StopPlaying()533 int StopPlaying()
534 {
535     HDF_LOGI("%{public}s", __func__);
536 #ifdef A2DP_HDI_SERVICE
537     BTAudioStreamState state = getStateFunc();
538     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
539     if (state != BTAudioStreamState::INVALID) {
540         stopPlayingFunc();
541     }
542     return HDF_SUCCESS;
543 #else
544     if (!g_proxy_) {
545         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
546         return RET_BAD_STATUS;
547     }
548     return g_proxy_->StopPlaying(g_proxy_->GetActiveSinkDevice());
549 #endif
550 }
551 
GetLatency(uint32_t & latency)552 int GetLatency(uint32_t &latency)
553 {
554     HDF_LOGD("%{public}s", __func__);
555 #ifdef A2DP_HDI_SERVICE
556     return (getLatencyFunc(latency) ? HDF_SUCCESS : HDF_FAILURE);
557 #else
558     return HDF_ERR_NOT_SUPPORT;
559 #endif
560 }
561 }
562 }
563