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