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 "audio_internal.h"
19 #include "i_bluetooth_a2dp_src.h"
20 #include "i_bluetooth_host.h"
21 #include "bluetooth_a2dp_src_observer.h"
22 #include "bluetooth_def.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "audio_bluetooth_manager.h"
26 
27 #ifdef A2DP_HDI_SERVICE
28 #include "bluetooth_audio_device.h"
29 #endif
30 
31 #define HDF_LOG_TAG BTAudioBluetoothManager
32 
33 namespace OHOS {
34 namespace Bluetooth {
35 using namespace OHOS::bluetooth;
36 
37 #ifdef A2DP_HDI_SERVICE
38 using namespace OHOS::bluetooth::audio;
39 static const char *g_bluetoothAudioDeviceSoPath = HDF_LIBRARY_FULL_PATH("libbluetooth_audio_session");
40 static void *g_ptrAudioDeviceHandle = NULL;
41 SetUpFunc setUpFunc;
42 TearDownFunc tearDownFunc;
43 GetStateFunc getStateFunc;
44 StartPlayingFunc startPlayingFunc;
45 SuspendPlayingFunc suspendPlayingFunc;
46 StopPlayingFunc stopPlayingFunc;
47 WriteFrameFunc writeFrameFunc;
48 GetLatencyFunc getLatencyFunc;
49 
50 SetUpFunc fastSetUpFunc;
51 TearDownFunc fastTearDownFunc;
52 GetStateFunc fastGetStateFunc;
53 StartPlayingFunc fastStartPlayingFunc;
54 SuspendPlayingFunc fastSuspendPlayingFunc;
55 StopPlayingFunc fastStopPlayingFunc;
56 ReqMmapBufferFunc fastReqMmapBufferFunc;
57 ReadMmapPositionFunc fastReadMmapPositionFunc;
58 GetLatencyFunc fastGetLatencyFunc;
59 #endif
60 
61 sptr<IBluetoothA2dpSrc> g_proxy_ = nullptr;
62 static sptr<BluetoothA2dpSrcObserver> g_btA2dpSrcObserverCallbacks = nullptr;
63 int g_playState = A2DP_NOT_PLAYING;
64 std::map<int, std::string> g_playdevices {};
65 std::mutex g_playStateMutex;
66 
AudioOnConnectionStateChanged(const RawAddress &device, int state, int cause)67 static void AudioOnConnectionStateChanged(const RawAddress &device, int state, int cause)
68 {
69     HDF_LOGI("%{public}s, state:%{public}d", __func__, state);
70     (void) state;
71     (void) cause;
72 }
73 
AudioOnPlayingStatusChanged(const RawAddress &device, int playingState, int error)74 static void AudioOnPlayingStatusChanged(const RawAddress &device, int playingState, int error)
75 {
76     HDF_LOGI("%{public}s, playingState:%{public}d", __func__, playingState);
77     std::lock_guard<std::mutex> lock(g_playStateMutex);
78     std::string addr = device.GetAddress();
79     if (playingState) {
80         for (const auto &it : g_playdevices) {
81             if (strcmp(it.second.c_str(), device.GetAddress().c_str()) == 0) {
82                 return;
83             }
84         }
85         g_playdevices.insert(std::make_pair(playingState, addr));
86         g_playState = playingState;
87     } else {
88         std::map<int, std::string>::iterator it;
89         for (it = g_playdevices.begin(); it != g_playdevices.end(); it++) {
90             if (strcmp(it->second.c_str(), device.GetAddress().c_str()) == 0) {
91                 g_playdevices.erase(it);
92                 break;
93             }
94         }
95         if (g_playdevices.empty()) {
96             g_playState = playingState;
97         }
98     }
99     (void) error;
100 }
101 
AudioOnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error)102 static void AudioOnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error)
103 {
104     (void) device;
105     (void) info;
106     (void) error;
107 }
108 
AudioOnMediaStackChanged(const RawAddress &device, int action)109 static void AudioOnMediaStackChanged(const RawAddress &device, int action)
110 {
111     (void) device;
112     (void) action;
113 }
114 
115 
116 static BtA2dpAudioCallback g_hdiCallbacks = {
117     .OnConnectionStateChanged = AudioOnConnectionStateChanged,
118     .OnPlayingStatusChanged = AudioOnPlayingStatusChanged,
119     .OnConfigurationChanged =  AudioOnConfigurationChanged,
120     .OnMediaStackChanged = AudioOnMediaStackChanged,
121 };
122 
GetPlayingState()123 int GetPlayingState()
124 {
125     HDF_LOGI("%{public}s: state:%{public}d", __func__, g_playState);
126     return g_playState;
127 }
128 
GetProxy()129 void GetProxy()
130 {
131     HDF_LOGI("%{public}s start", __func__);
132     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
133     if (!samgr) {
134         HDF_LOGE("%{public}s: error: no samgr", __func__);
135         return;
136     }
137 
138     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
139     if (!hostRemote) {
140         HDF_LOGE("%{public}s: failed: no hostRemote", __func__);
141         return;
142     }
143 
144     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
145     if (!hostProxy) {
146         HDF_LOGE("%{public}s: error: host no proxy", __func__);
147         return;
148     }
149 
150     sptr<IRemoteObject> remote = hostProxy->GetProfile("A2dpSrcServer");
151     if (!remote) {
152         HDF_LOGE("%{public}s: error: no remote", __func__);
153         return;
154     }
155 
156     g_proxy_ = iface_cast<IBluetoothA2dpSrc>(remote);
157     if (!g_proxy_) {
158         HDF_LOGE("%{public}s: error: no proxy", __func__);
159         return;
160     }
161 }
162 
RegisterObserver()163 void RegisterObserver()
164 {
165     HDF_LOGI("%{public}s", __func__);
166     g_btA2dpSrcObserverCallbacks = new (std::nothrow) BluetoothA2dpSrcObserver(&g_hdiCallbacks);
167     if (!g_btA2dpSrcObserverCallbacks) {
168         HDF_LOGE("%{public}s: g_btA2dpSrcObserverCallbacks is null", __func__);
169         return;
170     }
171     if (!g_proxy_) {
172         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
173         return;
174     }
175     g_proxy_->RegisterObserver(g_btA2dpSrcObserverCallbacks);
176 }
177 
DeRegisterObserver()178 void DeRegisterObserver()
179 {
180     HDF_LOGI("%{public}s", __func__);
181     if (!g_proxy_) {
182         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
183         return;
184     }
185     g_proxy_->DeregisterObserver(g_btA2dpSrcObserverCallbacks);
186 }
187 
188 #ifdef A2DP_HDI_SERVICE
189 #define GET_SYM_ERRPR_RET(handle, funcType, funcPtr, funcStr)       \
190     do {                                                            \
191         funcPtr = (funcType)dlsym(handle, funcStr);                 \
192         if (funcPtr == nullptr) {                                   \
193             HDF_LOGE("%{public}s: lib so func not found", funcStr); \
194             return false;                                           \
195         }                                                           \
196     } while (0)
197 
InitAudioDeviceSoHandle(const char *path)198 static bool InitAudioDeviceSoHandle(const char *path)
199 {
200     if (path == NULL) {
201         HDF_LOGE("%{public}s: path is NULL", __func__);
202         return false;
203     }
204     char pathBuf[PATH_MAX] = {'\0'};
205     if (realpath(path, pathBuf) == NULL) {
206         return false;
207     }
208     if (g_ptrAudioDeviceHandle == NULL) {
209         g_ptrAudioDeviceHandle = dlopen(pathBuf, RTLD_LAZY);
210         if (g_ptrAudioDeviceHandle == NULL) {
211             HDF_LOGE("%{public}s: open lib so fail, reason:%{public}s ", __func__, dlerror());
212             return false;
213         }
214         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, setUpFunc, "SetUp");
215         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, tearDownFunc, "TearDown");
216         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, getStateFunc, "GetState");
217         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartPlayingFunc, startPlayingFunc, "StartPlaying");
218         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, suspendPlayingFunc, "SuspendPlaying");
219         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, stopPlayingFunc, "StopPlaying");
220         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, WriteFrameFunc, writeFrameFunc, "WriteFrame");
221         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetLatencyFunc, getLatencyFunc, "GetLatency");
222 
223         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SetUpFunc, fastSetUpFunc, "FastSetUp");
224         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, TearDownFunc, fastTearDownFunc, "FastTearDown");
225         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetStateFunc, fastGetStateFunc, "FastGetState");
226         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StartPlayingFunc, fastStartPlayingFunc, "FastStartPlaying");
227         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, SuspendPlayingFunc, fastSuspendPlayingFunc, "FastSuspendPlaying");
228         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, StopPlayingFunc, fastStopPlayingFunc, "FastStopPlaying");
229         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, ReqMmapBufferFunc, fastReqMmapBufferFunc, "FastReqMmapBuffer");
230         GET_SYM_ERRPR_RET(
231             g_ptrAudioDeviceHandle, ReadMmapPositionFunc, fastReadMmapPositionFunc, "FastReadMmapPosition");
232         GET_SYM_ERRPR_RET(g_ptrAudioDeviceHandle, GetLatencyFunc, fastGetLatencyFunc, "FastGetLatency");
233     }
234     return true;
235 }
236 
SetUp()237 bool SetUp()
238 {
239     bool ret = false;
240     ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
241     if (ret == true) {
242         ret = setUpFunc();
243     }
244     if (ret == false) {
245         HDF_LOGE("%{public}s failed!", __func__);
246     }
247     return ret;
248 }
249 
TearDown()250 void TearDown()
251 {
252     tearDownFunc();
253 }
254 
FastSetUp()255 bool FastSetUp()
256 {
257     bool ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
258     if (ret) {
259         ret = fastSetUpFunc();
260     }
261     if (!ret) {
262         HDF_LOGE("%{public}s failed", __func__);
263     }
264     return ret;
265 }
266 
FastTearDown()267 void FastTearDown()
268 {
269     fastTearDownFunc();
270 }
271 
FastStartPlaying(uint32_t sampleRate, uint32_t channelCount, uint32_t format)272 int FastStartPlaying(uint32_t sampleRate, uint32_t channelCount, uint32_t format)
273 {
274     BTAudioStreamState state = fastGetStateFunc();
275     if (state != BTAudioStreamState::STARTED) {
276         HDF_LOGI("%{public}s, state=%{public}hhu", __func__, state);
277         if (!fastStartPlayingFunc(sampleRate, channelCount, format)) {
278             HDF_LOGE("%{public}s, fail to startPlaying", __func__);
279             return HDF_FAILURE;
280         }
281     }
282     return HDF_SUCCESS;
283 }
284 
FastSuspendPlaying()285 int FastSuspendPlaying()
286 {
287     int ret = 0;
288     BTAudioStreamState state = fastGetStateFunc();
289     if (state == BTAudioStreamState::STARTED) {
290         ret = (fastSuspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
291     } else {
292         HDF_LOGE("%{public}s, state=%{public}hhu is bad state", __func__, state);
293     }
294     return ret;
295 }
296 
FastStopPlaying()297 int FastStopPlaying()
298 {
299     BTAudioStreamState state = fastGetStateFunc();
300     HDF_LOGI("%{public}s, state=%{public}hhu", __func__, state);
301     if (state != BTAudioStreamState::INVALID) {
302         fastStopPlayingFunc();
303     }
304     return HDF_SUCCESS;
305 }
306 
FastReqMmapBuffer(int32_t ashmemLength)307 int FastReqMmapBuffer(int32_t ashmemLength)
308 {
309     return fastReqMmapBufferFunc(ashmemLength);
310 }
311 
FastReadMmapPosition(int64_t &sec, int64_t &nSec, uint64_t &frames)312 void FastReadMmapPosition(int64_t &sec, int64_t &nSec, uint64_t &frames)
313 {
314     fastReadMmapPositionFunc(sec, nSec, frames);
315 }
316 
FastGetLatency(uint32_t &latency)317 int FastGetLatency(uint32_t &latency)
318 {
319     return (fastGetLatencyFunc(latency) ? HDF_SUCCESS : HDF_FAILURE);
320 }
321 #endif
322 
WriteFrame(const uint8_t *data, uint32_t size, const HDI::Audio_Bluetooth::AudioSampleAttributes *attrs)323 int WriteFrame(const uint8_t *data, uint32_t size, const HDI::Audio_Bluetooth::AudioSampleAttributes *attrs)
324 {
325     HDF_LOGD("%{public}s", __func__);
326 #ifdef A2DP_HDI_SERVICE
327     BTAudioStreamState state = getStateFunc();
328     if (state != BTAudioStreamState::STARTED) {
329         HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
330         if (!startPlayingFunc(attrs->sampleRate, attrs->channelCount, static_cast<uint32_t>(attrs->format))) {
331             HDF_LOGE("%{public}s: fail to startPlaying", __func__);
332             return HDF_FAILURE;
333         }
334     }
335     return writeFrameFunc(data, size);
336 #else
337     if (!g_proxy_) {
338         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
339         return RET_BAD_STATUS;
340     }
341     if (g_playState == A2DP_NOT_PLAYING) {
342         HDF_LOGE("%{public}s: playState is not Streaming", __func__);
343         return RET_BAD_STATUS;
344     }
345     return g_proxy_->WriteFrame(data, size);
346 #endif
347 }
348 
StartPlaying()349 int StartPlaying()
350 {
351     HDF_LOGI("%{public}s", __func__);
352 #ifdef A2DP_HDI_SERVICE
353     return HDF_SUCCESS;
354 #else
355     if (!g_proxy_) {
356         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
357         return RET_BAD_STATUS;
358     }
359     return g_proxy_->StartPlaying(g_proxy_->GetActiveSinkDevice());
360 #endif
361 }
362 
SuspendPlaying()363 int SuspendPlaying()
364 {
365     HDF_LOGI("%{public}s", __func__);
366 #ifdef A2DP_HDI_SERVICE
367     int retval = 0;
368     BTAudioStreamState state = getStateFunc();
369     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
370     if (state == BTAudioStreamState::STARTED) {
371         retval = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
372     } else {
373         HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
374     }
375     return retval;
376 #else
377     if (!g_proxy_) {
378         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
379         return RET_BAD_STATUS;
380     }
381     return g_proxy_->SuspendPlaying(g_proxy_->GetActiveSinkDevice());
382 #endif
383 }
384 
StopPlaying()385 int StopPlaying()
386 {
387     HDF_LOGI("%{public}s", __func__);
388 #ifdef A2DP_HDI_SERVICE
389     BTAudioStreamState state = getStateFunc();
390     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
391     if (state != BTAudioStreamState::INVALID) {
392         stopPlayingFunc();
393     }
394     return HDF_SUCCESS;
395 #else
396     if (!g_proxy_) {
397         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
398         return RET_BAD_STATUS;
399     }
400     return g_proxy_->StopPlaying(g_proxy_->GetActiveSinkDevice());
401 #endif
402 }
403 
GetLatency(uint32_t &latency)404 int GetLatency(uint32_t &latency)
405 {
406     HDF_LOGD("%{public}s", __func__);
407 #ifdef A2DP_HDI_SERVICE
408     return (getLatencyFunc(latency) ? HDF_SUCCESS : HDF_FAILURE);
409 #else
410     return HDF_ERR_NOT_SUPPORT;
411 #endif
412 }
413 }
414 }
415