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