• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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", __func__, state);
206         if (!startPlayingFunc()) {
207             HDF_LOGE("%{public}s: fail to startPlaying", __func__);
208             return HDF_FAILURE;
209         }
210     }
211     return writeFrameFunc(data, size);
212 #else
213     if (!g_proxy_) {
214         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
215         return RET_BAD_STATUS;
216     }
217     if (g_playState == A2DP_NOT_PLAYING) {
218         HDF_LOGE("%{public}s: playState is not Streaming", __func__);
219         return RET_BAD_STATUS;
220     }
221     return g_proxy_->WriteFrame(data, size);
222 #endif
223 }
224 
StartPlaying()225 int StartPlaying()
226 {
227     HDF_LOGI("%{public}s", __func__);
228 #ifdef A2DP_HDI_SERVICE
229     return HDF_SUCCESS;
230 #else
231     if (!g_proxy_) {
232         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
233         return RET_BAD_STATUS;
234     }
235     return g_proxy_->StartPlaying(g_proxy_->GetActiveSinkDevice());
236 #endif
237 }
238 
SuspendPlaying()239 int SuspendPlaying()
240 {
241     HDF_LOGI("%{public}s", __func__);
242 #ifdef A2DP_HDI_SERVICE
243     int retval = 0;
244     BTAudioStreamState state = getStateFunc();
245     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
246     if (state == BTAudioStreamState::STARTED) {
247         retval = (suspendPlayingFunc() ? HDF_SUCCESS : HDF_FAILURE);
248     } else {
249         HDF_LOGE("%{public}s: state=%{public}hhu is bad state", __func__, state);
250     }
251     return retval;
252 #else
253     if (!g_proxy_) {
254         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
255         return RET_BAD_STATUS;
256     }
257     return g_proxy_->SuspendPlaying(g_proxy_->GetActiveSinkDevice());
258 #endif
259 }
260 
StopPlaying()261 int StopPlaying()
262 {
263     HDF_LOGI("%{public}s", __func__);
264 #ifdef A2DP_HDI_SERVICE
265     BTAudioStreamState state = getStateFunc();
266     HDF_LOGE("%{public}s: state=%{public}hhu", __func__, state);
267     if (state != BTAudioStreamState::INVALID) {
268         stopPlayingFunc();
269     }
270     return HDF_SUCCESS;
271 #else
272     if (!g_proxy_) {
273         HDF_LOGE("%{public}s: g_proxy_ is null", __func__);
274         return RET_BAD_STATUS;
275     }
276     return g_proxy_->StopPlaying(g_proxy_->GetActiveSinkDevice());
277 #endif
278 }
279 }
280 }