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