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 #endif
65
66 sptr<IBluetoothA2dpSrc> g_proxy_ = nullptr;
67 static sptr<BluetoothA2dpSrcObserver> g_btA2dpSrcObserverCallbacks = nullptr;
68 int g_playState = A2DP_NOT_PLAYING;
69 std::map<int, std::string> g_playdevices {};
70 std::mutex g_playStateMutex;
71
AudioOnConnectionStateChanged(const RawAddress & device,int state,int cause)72 static void AudioOnConnectionStateChanged(const RawAddress &device, int state, int cause)
73 {
74 HDF_LOGI("%{public}s, state:%{public}d", __func__, state);
75 (void) state;
76 (void) cause;
77 }
78
AudioOnPlayingStatusChanged(const RawAddress & device,int playingState,int error)79 static void AudioOnPlayingStatusChanged(const RawAddress &device, int playingState, int error)
80 {
81 HDF_LOGI("%{public}s, playingState:%{public}d", __func__, playingState);
82 std::lock_guard<std::mutex> lock(g_playStateMutex);
83 std::string addr = device.GetAddress();
84 if (playingState) {
85 for (const auto &it : g_playdevices) {
86 if (strcmp(it.second.c_str(), device.GetAddress().c_str()) == 0) {
87 return;
88 }
89 }
90 g_playdevices.insert(std::make_pair(playingState, addr));
91 g_playState = playingState;
92 } else {
93 std::map<int, std::string>::iterator it;
94 for (it = g_playdevices.begin(); it != g_playdevices.end(); it++) {
95 if (strcmp(it->second.c_str(), device.GetAddress().c_str()) == 0) {
96 g_playdevices.erase(it);
97 break;
98 }
99 }
100 if (g_playdevices.empty()) {
101 g_playState = playingState;
102 }
103 }
104 (void) error;
105 }
106
AudioOnConfigurationChanged(const RawAddress & device,const BluetoothA2dpCodecInfo & info,int error)107 static void AudioOnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error)
108 {
109 (void) device;
110 (void) info;
111 (void) error;
112 }
113
AudioOnMediaStackChanged(const RawAddress & device,int action)114 static void AudioOnMediaStackChanged(const RawAddress &device, int action)
115 {
116 (void) device;
117 (void) action;
118 }
119
120
121 static BtA2dpAudioCallback g_hdiCallbacks = {
122 .OnConnectionStateChanged = AudioOnConnectionStateChanged,
123 .OnPlayingStatusChanged = AudioOnPlayingStatusChanged,
124 .OnConfigurationChanged = AudioOnConfigurationChanged,
125 .OnMediaStackChanged = AudioOnMediaStackChanged,
126 };
127
GetPlayingState()128 int GetPlayingState()
129 {
130 HDF_LOGI("%{public}s: state:%{public}d", __func__, g_playState);
131 return g_playState;
132 }
133
GetProxy()134 void GetProxy()
135 {
136 HDF_LOGI("%{public}s start", __func__);
137 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
138 if (!samgr) {
139 HDF_LOGE("%{public}s: error: no samgr", __func__);
140 return;
141 }
142
143 sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
144 if (!hostRemote) {
145 HDF_LOGE("%{public}s: failed: no hostRemote", __func__);
146 return;
147 }
148
149 sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
150 if (!hostProxy) {
151 HDF_LOGE("%{public}s: error: host no proxy", __func__);
152 return;
153 }
154
155 sptr<IRemoteObject> remote = hostProxy->GetProfile("A2dpSrcServer");
156 if (!remote) {
157 HDF_LOGE("%{public}s: error: no remote", __func__);
158 return;
159 }
160
161 g_proxy_ = iface_cast<IBluetoothA2dpSrc>(remote);
162 if (!g_proxy_) {
163 HDF_LOGE("%{public}s: error: no proxy", __func__);
164 return;
165 }
166 }
167
RegisterObserver()168 void RegisterObserver()
169 {
170 HDF_LOGI("%{public}s", __func__);
171 g_btA2dpSrcObserverCallbacks = new (std::nothrow) BluetoothA2dpSrcObserver(&g_hdiCallbacks);
172 if (!g_btA2dpSrcObserverCallbacks) {
173 HDF_LOGE("%{public}s: g_btA2dpSrcObserverCallbacks is null", __func__);
174 return;
175 }
176 if (!g_proxy_) {
177 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
178 return;
179 }
180 g_proxy_->RegisterObserver(g_btA2dpSrcObserverCallbacks);
181 }
182
DeRegisterObserver()183 void DeRegisterObserver()
184 {
185 HDF_LOGI("%{public}s", __func__);
186 if (!g_proxy_) {
187 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
188 return;
189 }
190 g_proxy_->DeregisterObserver(g_btA2dpSrcObserverCallbacks);
191 }
192
193 #ifdef A2DP_HDI_SERVICE
194 #define GET_SYM_ERRPR_RET(handle, funcType, funcPtr, funcStr) \
195 do { \
196 funcPtr = (funcType)dlsym(handle, funcStr); \
197 if (funcPtr == nullptr) { \
198 HDF_LOGE("%{public}s: lib so func not found", funcStr); \
199 return false; \
200 } \
201 } while (0)
202
InitAudioDeviceSoHandle(const char * path)203 static bool InitAudioDeviceSoHandle(const char *path)
204 {
205 if (path == NULL) {
206 HDF_LOGE("%{public}s: path is NULL", __func__);
207 return false;
208 }
209 char pathBuf[PATH_MAX] = {'\0'};
210 if (realpath(path, pathBuf) == NULL) {
211 return false;
212 }
213 if (g_ptrAudioDeviceHandle == NULL) {
214 g_ptrAudioDeviceHandle = dlopen(pathBuf, RTLD_LAZY);
215 if (g_ptrAudioDeviceHandle == NULL) {
216 HDF_LOGE("%{public}s: open lib so fail, reason:%{public}s ", __func__, dlerror());
217 return false;
218 }
219 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, setUpFunc, "SetUp");
220 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, tearDownFunc, "TearDown");
221 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, getStateFunc, "GetState");
222 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartPlayingFunc, startPlayingFunc, "StartPlaying");
223 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, suspendPlayingFunc, "SuspendPlaying");
224 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, stopPlayingFunc, "StopPlaying");
225 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, WriteFrameFunc, writeFrameFunc, "WriteFrame");
226 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetLatencyFunc, getLatencyFunc, "GetLatency");
227
228 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, fastSetUpFunc, "FastSetUp");
229 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, fastTearDownFunc, "FastTearDown");
230 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, fastGetStateFunc, "FastGetState");
231 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartPlayingFunc, fastStartPlayingFunc, "FastStartPlaying");
232 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, fastSuspendPlayingFunc, "FastSuspendPlaying");
233 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, fastStopPlayingFunc, "FastStopPlaying");
234 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, ReqMmapBufferFunc, fastReqMmapBufferFunc, "FastReqMmapBuffer");
235 GET_SYM_ERRPR_RET(
236 g_ptrAudioDeviceHandle, ReadMmapPositionFunc, fastReadMmapPositionFunc, "FastReadMmapPosition");
237 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetLatencyFunc, fastGetLatencyFunc, "FastGetLatency");
238 GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetRealStateFunc, getRealStateFunc, "GetRealState");
239 GET_SYM_ERRPR_RET(
240 g_ptrAudioDeviceHandle, GetRenderMixerStateFunc, getRenderMixerStateFunc, "GetRenderMixerState");
241 }
242 return true;
243 }
244
SetUp()245 bool SetUp()
246 {
247 bool ret = false;
248 ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
249 if (ret == true) {
250 ret = setUpFunc();
251 }
252 if (ret == false) {
253 HDF_LOGE("%{public}s failed!", __func__);
254 }
255 return ret;
256 }
257
TearDown()258 void TearDown()
259 {
260 tearDownFunc();
261 }
262
FastSetUp()263 bool FastSetUp()
264 {
265 bool ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
266 if (ret) {
267 ret = fastSetUpFunc();
268 }
269 if (!ret) {
270 HDF_LOGE("%{public}s failed", __func__);
271 }
272 return ret;
273 }
274
FastTearDown()275 void FastTearDown()
276 {
277 fastTearDownFunc();
278 }
279
FastStartPlaying(uint32_t sampleRate,uint32_t channelCount,uint32_t format)280 int FastStartPlaying(uint32_t sampleRate, uint32_t channelCount, uint32_t format)
281 {
282 BTAudioStreamState state = fastGetStateFunc();
283 if (!g_allowAudioStart.load()) {
284 HDF_LOGE("not allow to start fast render, state=%{public}hhu", state);
285 return HDF_FAILURE;
286 } else if (state != BTAudioStreamState::STARTED) {
287 HDF_LOGI("%{public}s, state=%{public}hhu", __func__, state);
288 if (!fastStartPlayingFunc(sampleRate, channelCount, format)) {
289 HDF_LOGE("%{public}s, fail to startPlaying", __func__);
290 return HDF_FAILURE;
291 }
292 }
293 return HDF_SUCCESS;
294 }
295
FastSuspendPlayingFromParam()296 int FastSuspendPlayingFromParam()
297 {
298 int ret = 0;
299 RenderMixerState renderState = getRenderMixerStateFunc();
300 if (!g_allowAudioStart.load()) {
301 if (renderState == RenderMixerState::INITED || renderState == RenderMixerState::NORMAL_ON_MIX_STOP) {
302 HDF_LOGE("fast render is already stopping or stopped");
303 return ret;
304 }
305 }
306
307 BTAudioStreamState state = fastGetStateFunc();
308 BTAudioStreamState realState = getRealStateFunc();
309 g_allowAudioStart = false;
310 if (state == BTAudioStreamState::STARTED) {
311 HDF_LOGI("%{public}s", __func__);
312 ret = (fastSuspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
313 } else if (realState == BTAudioStreamState::STARTING && renderState == RenderMixerState::FAST_STARTED) {
314 HDF_LOGI("%{public}s fast render starting, so stopPlaying", __func__);
315 ret = (fastStopPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
316 } else {
317 HDF_LOGE("%{public}s, state=%{public}hhu is bad state, realState=%{public}hhu, renderState=%{public}hhu",
318 __func__, state, realState, renderState);
319 }
320 return ret;
321 }
322
FastSuspendPlaying()323 int FastSuspendPlaying()
324 {
325 int ret = 0;
326 BTAudioStreamState state = fastGetStateFunc();
327 if (state == BTAudioStreamState::STARTED) {
328 ret = (fastSuspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
329 } else {
330 HDF_LOGE("%{public}s, state=%{public}hhu is bad state", __func__, state);
331 }
332 return ret;
333 }
334
FastStopPlaying()335 int FastStopPlaying()
336 {
337 BTAudioStreamState state = fastGetStateFunc();
338 HDF_LOGI("%{public}s, state=%{public}hhu", __func__, state);
339 if (state != BTAudioStreamState::INVALID) {
340 fastStopPlayingFunc();
341 }
342 return HDF_SUCCESS;
343 }
344
FastReqMmapBuffer(int32_t ashmemLength)345 int FastReqMmapBuffer(int32_t ashmemLength)
346 {
347 return fastReqMmapBufferFunc(ashmemLength);
348 }
349
FastReadMmapPosition(int64_t & sec,int64_t & nSec,uint64_t & frames)350 void FastReadMmapPosition(int64_t &sec, int64_t &nSec, uint64_t &frames)
351 {
352 fastReadMmapPositionFunc(sec, nSec, frames);
353 }
354
FastGetLatency(uint32_t & latency)355 int FastGetLatency(uint32_t &latency)
356 {
357 return (fastGetLatencyFunc(latency) ? HDF_SUCCESS : HDF_FAILURE);
358 }
359
SuspendPlayingFromParam()360 int SuspendPlayingFromParam()
361 {
362 int retVal = 0;
363 RenderMixerState renderState = getRenderMixerStateFunc();
364 if (!g_allowAudioStart.load()) {
365 if (renderState == RenderMixerState::INITED || renderState == RenderMixerState::FAST_ON_MIX_STOP) {
366 HDF_LOGE("normal render is already stopping or stopped");
367 return retVal;
368 }
369 }
370
371 BTAudioStreamState state = getStateFunc();
372 BTAudioStreamState realState = getRealStateFunc();
373 g_allowAudioStart = false;
374 if (state == BTAudioStreamState::STARTED) {
375 HDF_LOGI("%{public}s", __func__);
376 retVal = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
377 } else if (realState == BTAudioStreamState::STARTING && renderState == RenderMixerState::INITED) {
378 HDF_LOGI("%{public}s normal render starting, so stopPlaying", __func__);
379 retVal = (stopPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
380 } else {
381 HDF_LOGE("%{public}s, state=%{public}hhu is bad state, realState=%{public}hhu, renderState=%{public}hhu",
382 __func__, state, realState, renderState);
383 }
384 return retVal;
385 }
386
UnBlockStart()387 void UnBlockStart()
388 {
389 g_allowAudioStart = true;
390 }
391 #endif
392
WriteFrame(const uint8_t * data,uint32_t size,const HDI::Audio_Bluetooth::AudioSampleAttributes * attrs)393 int WriteFrame(const uint8_t *data, uint32_t size, const HDI::Audio_Bluetooth::AudioSampleAttributes *attrs)
394 {
395 HDF_LOGD("%{public}s", __func__);
396 #ifdef A2DP_HDI_SERVICE
397 BTAudioStreamState state = getStateFunc();
398 if (!g_allowAudioStart.load()) {
399 HDF_LOGE("not allow to start normal render, state=%{public}hhu", state);
400 return HDF_FAILURE;
401 } else if (state != BTAudioStreamState::STARTED) {
402 HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
403 if (!startPlayingFunc(attrs->sampleRate, attrs->channelCount, static_cast<uint32_t>(attrs->format))) {
404 HDF_LOGE("%{public}s: fail to startPlaying", __func__);
405 return HDF_FAILURE;
406 }
407 }
408 return writeFrameFunc(data, size);
409 #else
410 if (!g_proxy_) {
411 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
412 return RET_BAD_STATUS;
413 }
414 if (g_playState == A2DP_NOT_PLAYING) {
415 HDF_LOGE("%{public}s: playState is not Streaming", __func__);
416 return RET_BAD_STATUS;
417 }
418 return g_proxy_->WriteFrame(data, size);
419 #endif
420 }
421
StartPlaying()422 int StartPlaying()
423 {
424 HDF_LOGI("%{public}s", __func__);
425 #ifdef A2DP_HDI_SERVICE
426 return HDF_SUCCESS;
427 #else
428 if (!g_proxy_) {
429 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
430 return RET_BAD_STATUS;
431 }
432 return g_proxy_->StartPlaying(g_proxy_->GetActiveSinkDevice());
433 #endif
434 }
435
SuspendPlaying()436 int SuspendPlaying()
437 {
438 #ifdef A2DP_HDI_SERVICE
439 int retval = 0;
440 BTAudioStreamState state = getStateFunc();
441 HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
442 if (state == BTAudioStreamState::STARTED) {
443 retval = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
444 } else {
445 HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
446 }
447 return retval;
448 #else
449 HDF_LOGI("%{public}s", __func__);
450 if (!g_proxy_) {
451 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
452 return RET_BAD_STATUS;
453 }
454 return g_proxy_->SuspendPlaying(g_proxy_->GetActiveSinkDevice());
455 #endif
456 }
457
StopPlaying()458 int StopPlaying()
459 {
460 HDF_LOGI("%{public}s", __func__);
461 #ifdef A2DP_HDI_SERVICE
462 BTAudioStreamState state = getStateFunc();
463 HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
464 if (state != BTAudioStreamState::INVALID) {
465 stopPlayingFunc();
466 }
467 return HDF_SUCCESS;
468 #else
469 if (!g_proxy_) {
470 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
471 return RET_BAD_STATUS;
472 }
473 return g_proxy_->StopPlaying(g_proxy_->GetActiveSinkDevice());
474 #endif
475 }
476
GetLatency(uint32_t & latency)477 int GetLatency(uint32_t &latency)
478 {
479 HDF_LOGI("%{public}s", __func__);
480 #ifdef A2DP_HDI_SERVICE
481 return (getLatencyFunc(latency) ? HDF_SUCCESS : HDF_FAILURE);
482 #else
483 return HDF_ERR_NOT_SUPPORT;
484 #endif
485 }
486 }
487 }
488