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 <hdf_log.h>
17 #include "audio_internal.h"
18 #include "i_bluetooth_a2dp_src.h"
19 #include "i_bluetooth_host.h"
20 #include "bluetooth_a2dp_src_observer.h"
21 #include "bluetooth_def.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 #include "audio_bluetooth_manager.h"
25
26 #ifdef A2DP_HDI_SERVICE
27 #include "bluetooth_audio_device.h"
28 #endif
29
30 #define HDF_LOG_TAG BTAudioBluetoothManager
31
32 namespace OHOS {
33 namespace Bluetooth {
34 using namespace OHOS::bluetooth;
35
36 #ifdef A2DP_HDI_SERVICE
37 using namespace OHOS::bluetooth::audio;
38 static const char *g_bluetoothAudioDeviceSoPath = HDF_LIBRARY_FULL_PATH("libbluetooth_audio_session");
39 static void *g_ptrAudioDeviceHandle = NULL;
40 SetUpFunc setUpFunc;
41 TearDownFunc tearDownFunc;
42 GetStateFunc getStateFunc;
43 StartPlayingFunc startPlayingFunc;
44 SuspendPlayingFunc suspendPlayingFunc;
45 StopPlayingFunc stopPlayingFunc;
46 WriteFrameFunc writeFrameFunc;
47 #endif
48
49 sptr<IBluetoothA2dpSrc> g_proxy_ = nullptr;
50 static sptr<BluetoothA2dpSrcObserver> g_btA2dpSrcObserverCallbacks = nullptr;
51 int g_playState = A2DP_NOT_PLAYING;
52
AudioOnConnectionStateChanged(const RawAddress & device,int state)53 static void AudioOnConnectionStateChanged(const RawAddress &device, int state)
54 {
55 HDF_LOGI("%{public}s, state:%{public}d", __func__, state);
56 (void) state;
57 }
58
AudioOnPlayingStatusChanged(const RawAddress & device,int playingState,int error)59 static void AudioOnPlayingStatusChanged(const RawAddress &device, int playingState, int error)
60 {
61 HDF_LOGI("%{public}s, playingState:%{public}d", __func__, playingState);
62 g_playState = playingState;
63 (void) error;
64 }
65
AudioOnConfigurationChanged(const RawAddress & device,const BluetoothA2dpCodecInfo & info,int error)66 static void AudioOnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error)
67 {
68 (void) device;
69 (void) info;
70 (void) error;
71 }
72
73
74 static BtA2dpAudioCallback g_hdiCallbacks = {
75 .OnConnectionStateChanged = AudioOnConnectionStateChanged,
76 .OnPlayingStatusChanged = AudioOnPlayingStatusChanged,
77 .OnConfigurationChanged = AudioOnConfigurationChanged,
78 };
79
GetPlayingState()80 int GetPlayingState()
81 {
82 HDF_LOGI("%{public}s: state:%{public}d", __func__, g_playState);
83 return g_playState;
84 }
85
GetProxy()86 void GetProxy()
87 {
88 HDF_LOGI("%{public}s start", __func__);
89 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
90 if (!samgr) {
91 HDF_LOGE("%{public}s: error: no samgr", __func__);
92 return;
93 }
94
95 sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
96 if (!hostRemote) {
97 HDF_LOGE("%{public}s: failed: no hostRemote", __func__);
98 return;
99 }
100
101 sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
102 if (!hostProxy) {
103 HDF_LOGE("%{public}s: error: host no proxy", __func__);
104 return;
105 }
106
107 sptr<IRemoteObject> remote = hostProxy->GetProfile("A2dpSrcServer");
108 if (!remote) {
109 HDF_LOGE("%{public}s: error: no remote", __func__);
110 return;
111 }
112
113 g_proxy_ = iface_cast<IBluetoothA2dpSrc>(remote);
114 if (!g_proxy_) {
115 HDF_LOGE("%{public}s: error: no proxy", __func__);
116 return;
117 }
118 }
119
RegisterObserver()120 void RegisterObserver()
121 {
122 HDF_LOGI("%{public}s", __func__);
123 g_btA2dpSrcObserverCallbacks = new (std::nothrow) BluetoothA2dpSrcObserver(&g_hdiCallbacks);
124 if (!g_btA2dpSrcObserverCallbacks) {
125 HDF_LOGE("%{public}s: g_btA2dpSrcObserverCallbacks is null", __func__);
126 return;
127 }
128 if (!g_proxy_) {
129 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
130 return;
131 }
132 g_proxy_->RegisterObserver(g_btA2dpSrcObserverCallbacks);
133 }
134
DeRegisterObserver()135 void DeRegisterObserver()
136 {
137 HDF_LOGI("%{public}s", __func__);
138 if (!g_proxy_) {
139 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
140 return;
141 }
142 g_proxy_->DeregisterObserver(g_btA2dpSrcObserverCallbacks);
143 }
144
145 #ifdef A2DP_HDI_SERVICE
InitAudioDeviceSoHandle(const char * path)146 static bool InitAudioDeviceSoHandle(const char* path)
147 {
148 if (path == NULL) {
149 HDF_LOGE("%{public}s: path is NULL", __func__);
150 return false;
151 }
152 char pathBuf[PATH_MAX] = {'\0'};
153 if (realpath(path, pathBuf) == NULL) {
154 return false;
155 }
156 if (g_ptrAudioDeviceHandle == NULL) {
157 g_ptrAudioDeviceHandle = dlopen(pathBuf, RTLD_LAZY);
158 if (g_ptrAudioDeviceHandle == NULL) {
159 HDF_LOGE("%{public}s: open lib so fail, reason:%{public}s ", __func__, dlerror());
160 return false;
161 }
162
163 setUpFunc = (SetUpFunc)dlsym(g_ptrAudioDeviceHandle, "SetUp");
164 tearDownFunc = (TearDownFunc)dlsym(g_ptrAudioDeviceHandle, "TearDown");
165 getStateFunc = (GetStateFunc)dlsym(g_ptrAudioDeviceHandle, "GetState");
166 startPlayingFunc = (StartPlayingFunc)dlsym(g_ptrAudioDeviceHandle, "StartPlaying");
167 suspendPlayingFunc = (SuspendPlayingFunc)dlsym(g_ptrAudioDeviceHandle, "SuspendPlaying");
168 stopPlayingFunc = (StopPlayingFunc)dlsym(g_ptrAudioDeviceHandle, "StopPlaying");
169 writeFrameFunc = (WriteFrameFunc)dlsym(g_ptrAudioDeviceHandle, "WriteFrame");
170 if (setUpFunc == NULL || tearDownFunc == NULL || getStateFunc == NULL || startPlayingFunc == NULL ||
171 suspendPlayingFunc == NULL || stopPlayingFunc == NULL || writeFrameFunc == NULL) {
172 HDF_LOGE("%{public}s: lib so func not found", __func__);
173 return false;
174 }
175 }
176 return true;
177 }
178
SetUp()179 bool SetUp()
180 {
181 bool ret = false;
182 ret = InitAudioDeviceSoHandle(g_bluetoothAudioDeviceSoPath);
183 if (ret == true) {
184 ret = setUpFunc();
185 }
186 if (ret == false) {
187 HDF_LOGE("%{public}s failed!", __func__);
188 }
189 return ret;
190 }
191
TearDown()192 void TearDown()
193 {
194 tearDownFunc();
195 }
196 #endif
197
198
WriteFrame(const uint8_t * data,uint32_t size)199 int WriteFrame(const uint8_t *data, uint32_t size)
200 {
201 HDF_LOGI("%{public}s", __func__);
202 #ifdef A2DP_HDI_SERVICE
203 BTAudioStreamState state = getStateFunc();
204 if (state != BTAudioStreamState::STARTED) {
205 HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
206 return RET_BAD_STATUS;
207 }
208 return writeFrameFunc(data, size);
209 #else
210 if (!g_proxy_) {
211 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
212 return RET_BAD_STATUS;
213 }
214 if (g_playState == A2DP_NOT_PLAYING) {
215 HDF_LOGE("%{public}s: playState is not Streaming", __func__);
216 return RET_BAD_STATUS;
217 }
218 return g_proxy_->WriteFrame(data, size);
219 #endif
220 }
221
StartPlaying()222 int StartPlaying()
223 {
224 HDF_LOGI("%{public}s", __func__);
225 #ifdef A2DP_HDI_SERVICE
226 int retval = 0;
227 BTAudioStreamState state = getStateFunc();
228 HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
229 if (state == BTAudioStreamState::IDLE) {
230 retval = (startPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
231 } else {
232 HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
233 }
234 return retval;
235 #else
236 if (!g_proxy_) {
237 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
238 return RET_BAD_STATUS;
239 }
240 return g_proxy_->StartPlaying(g_proxy_->GetActiveSinkDevice());
241 #endif
242 }
243
SuspendPlaying()244 int SuspendPlaying()
245 {
246 HDF_LOGI("%{public}s", __func__);
247 #ifdef A2DP_HDI_SERVICE
248 int retval = 0;
249 BTAudioStreamState state = getStateFunc();
250 HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
251 if (state == BTAudioStreamState::STARTED) {
252 retval = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
253 } else {
254 HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
255 }
256 return retval;
257 #else
258 if (!g_proxy_) {
259 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
260 return RET_BAD_STATUS;
261 }
262 return g_proxy_->SuspendPlaying(g_proxy_->GetActiveSinkDevice());
263 #endif
264 }
265
StopPlaying()266 int StopPlaying()
267 {
268 HDF_LOGI("%{public}s", __func__);
269 #ifdef A2DP_HDI_SERVICE
270 BTAudioStreamState state = getStateFunc();
271 HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
272 if (state != BTAudioStreamState::INVALID) {
273 stopPlayingFunc();
274 }
275 return HDF_SUCCESS;
276 #else
277 if (!g_proxy_) {
278 HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
279 return RET_BAD_STATUS;
280 }
281 return g_proxy_->StopPlaying(g_proxy_->GetActiveSinkDevice());
282 #endif
283 }
284 }
285 }