1 /*
2 * Copyright (C) 2021-2022 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 "bluetooth_def.h"
17 #include "bluetooth_errorcode.h"
18 #include "bluetooth_hitrace.h"
19 #include "bluetooth_log.h"
20 #include "bluetooth_utils_server.h"
21 #include "hisysevent.h"
22 #include "interface_profile_manager.h"
23 #include "interface_profile_a2dp_src.h"
24 #include "remote_observer_list.h"
25 #include "interface_adapter_manager.h"
26 #include "permission_utils.h"
27 #include "bluetooth_a2dp_source_server.h"
28
29 namespace OHOS {
30 namespace Bluetooth {
31 class A2dpSourceObserver : public IA2dpObserver {
32 public:
33 A2dpSourceObserver() = default;
34 ~A2dpSourceObserver() override = default;
35
OnConnectionStateChanged(const RawAddress & device,int state)36 void OnConnectionStateChanged(const RawAddress &device, int state) override
37 {
38 HILOGI("addr: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state);
39 if (state == static_cast<int>(BTConnectState::CONNECTED) ||
40 state == static_cast<int>(BTConnectState::DISCONNECTED)) {
41 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "A2DP_CONNECTED_STATE",
42 OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "STATE", state);
43 }
44 observers_->ForEach([device, state](sptr<IBluetoothA2dpSourceObserver> observer) {
45 observer->OnConnectionStateChanged(device, state);
46 });
47 }
48
OnPlayingStatusChaned(const RawAddress & device,int playingState,int error)49 void OnPlayingStatusChaned(const RawAddress &device, int playingState, int error) override
50 {
51 HILOGI("addr: %{public}s, state: %{public}d, error: %{public}d",
52 GET_ENCRYPT_ADDR(device), playingState, error);
53 observers_->ForEach([device, playingState, error](sptr<IBluetoothA2dpSourceObserver> observer) {
54 observer->OnPlayingStatusChanged(device, playingState, error);
55 });
56 }
57
OnConfigurationChanged(const RawAddress & device,const A2dpSrcCodecInfo & info,int error)58 void OnConfigurationChanged(const RawAddress &device, const A2dpSrcCodecInfo &info, int error) override
59 {
60 HILOGI("addr: %{public}s, error: %{public}d", GET_ENCRYPT_ADDR(device), error);
61 observers_->ForEach([device, info, error](sptr<IBluetoothA2dpSourceObserver> observer) {
62 BluetoothA2dpCodecInfo tmpInfo {};
63 tmpInfo.bitsPerSample = info.bitsPerSample;
64 tmpInfo.channelMode = info.channelMode;
65 tmpInfo.codecPriority = info.codecPriority;
66 tmpInfo.codecType = info.codecType;
67 tmpInfo.sampleRate = info.sampleRate;
68 tmpInfo.codecSpecific1 = info.codecSpecific1;
69 tmpInfo.codecSpecific2 = info.codecSpecific2;
70 tmpInfo.codecSpecific3 = info.codecSpecific3;
71 tmpInfo.codecSpecific4 = info.codecSpecific4;
72
73 observer->OnConfigurationChanged(device, tmpInfo, error);
74 });
75 }
76
SetObserver(RemoteObserverList<IBluetoothA2dpSourceObserver> * observers)77 void SetObserver(RemoteObserverList<IBluetoothA2dpSourceObserver> *observers)
78 {
79 observers_ = observers;
80 }
81
82 private:
83 RemoteObserverList<IBluetoothA2dpSourceObserver> *observers_;
84 };
85
86 struct BluetoothA2dpSourceServer::impl {
87 impl();
88 ~impl();
89
90 /// sys state observer
91 class SystemStateObserver;
92 std::unique_ptr<SystemStateObserver> systemStateObserver_ = nullptr;
93
94 RemoteObserverList<IBluetoothA2dpSourceObserver> observers_;
95 std::unique_ptr<A2dpSourceObserver> observerImp_{std::make_unique<A2dpSourceObserver>()};
96 IProfileA2dpSrc *a2dpSrcService_ = nullptr;
97 };
98
99 class BluetoothA2dpSourceServer::impl::SystemStateObserver : public ISystemStateObserver {
100 public:
SystemStateObserver(BluetoothA2dpSourceServer::impl * pimpl)101 SystemStateObserver(BluetoothA2dpSourceServer::impl *pimpl) : pimpl_(pimpl) {};
102 ~SystemStateObserver() override = default;
103
OnSystemStateChange(const BTSystemState state)104 void OnSystemStateChange(const BTSystemState state) override
105 {
106 IProfileManager *serviceMgr = IProfileManager::GetInstance();
107 if (!pimpl_) {
108 HILOGI("failed: pimpl_ is null");
109 return;
110 }
111
112 switch (state) {
113 case BTSystemState::ON:
114 if (serviceMgr != nullptr) {
115 pimpl_->a2dpSrcService_ =
116 (IProfileA2dpSrc *)serviceMgr->GetProfileService(PROFILE_NAME_A2DP_SRC);
117 if (pimpl_->a2dpSrcService_ != nullptr) {
118 pimpl_->a2dpSrcService_->RegisterObserver(pimpl_->observerImp_.get());
119 }
120 }
121 break;
122 case BTSystemState::OFF:
123 pimpl_->a2dpSrcService_ = nullptr;
124 break;
125 default:
126 break;
127 }
128 }
129
130 private:
131 BluetoothA2dpSourceServer::impl *pimpl_ = nullptr;
132 };
133
impl()134 BluetoothA2dpSourceServer::impl::impl()
135 {
136 HILOGI("starts");
137 }
138
~impl()139 BluetoothA2dpSourceServer::impl::~impl()
140 {
141 HILOGI("starts");
142 }
143
BluetoothA2dpSourceServer()144 BluetoothA2dpSourceServer::BluetoothA2dpSourceServer()
145 {
146 HILOGI("starts");
147 pimpl = std::make_unique<impl>();
148 pimpl->observerImp_->SetObserver(&(pimpl->observers_));
149 pimpl->systemStateObserver_ = std::make_unique<impl::SystemStateObserver>(pimpl.get());
150 IAdapterManager::GetInstance()->RegisterSystemStateObserver(*(pimpl->systemStateObserver_));
151
152 IProfileManager *serviceMgr = IProfileManager::GetInstance();
153 if (serviceMgr != nullptr) {
154 pimpl->a2dpSrcService_ = (IProfileA2dpSrc *)serviceMgr->GetProfileService(PROFILE_NAME_A2DP_SRC);
155 if (pimpl->a2dpSrcService_ != nullptr) {
156 pimpl->a2dpSrcService_->RegisterObserver(pimpl->observerImp_.get());
157 }
158 }
159 }
160
~BluetoothA2dpSourceServer()161 BluetoothA2dpSourceServer::~BluetoothA2dpSourceServer()
162 {
163 HILOGI("starts");
164 IAdapterManager::GetInstance()->DeregisterSystemStateObserver(*(pimpl->systemStateObserver_));
165 if (pimpl->a2dpSrcService_ != nullptr) {
166 pimpl->a2dpSrcService_->DeregisterObserver(pimpl->observerImp_.get());
167 }
168 }
169
RegisterObserver(const sptr<IBluetoothA2dpSourceObserver> & observer)170 void BluetoothA2dpSourceServer::RegisterObserver(const sptr<IBluetoothA2dpSourceObserver> &observer)
171 {
172 HILOGI("starts");
173 if (observer == nullptr) {
174 HILOGI("observer is null");
175 return;
176 }
177 auto func = std::bind(&BluetoothA2dpSourceServer::DeregisterObserver, this, std::placeholders::_1);
178 pimpl->observers_.Register(observer, func);
179 if (pimpl->a2dpSrcService_ == nullptr) {
180 return;
181 }
182 // During A2DP HDF Registration, check the current status and callback
183 RawAddress device = GetActiveSinkDevice();
184 int state = static_cast<int>(BTConnectState::DISCONNECTED);
185 GetDeviceState(static_cast<const RawAddress &>(device), state);
186 if (state == static_cast<int>(BTConnectState::CONNECTED)) {
187 HILOGI("onConnectionStateChanged");
188 observer->OnConnectionStateChanged(device, state);
189 }
190 }
191
DeregisterObserver(const sptr<IBluetoothA2dpSourceObserver> & observer)192 void BluetoothA2dpSourceServer::DeregisterObserver(const sptr<IBluetoothA2dpSourceObserver> &observer)
193 {
194 HILOGI("starts");
195 if (observer == nullptr) {
196 HILOGE("observer is null");
197 return;
198 }
199
200 if (pimpl != nullptr) {
201 pimpl->observers_.Deregister(observer);
202 }
203 }
204
Connect(const RawAddress & device)205 int32_t BluetoothA2dpSourceServer::Connect(const RawAddress &device)
206 {
207 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
208 if (PermissionUtils::VerifyDiscoverBluetoothPermission() == PERMISSION_DENIED) {
209 HILOGE("Connect error, check permission failed");
210 return BT_ERR_SYSTEM_PERMISSION_FAILED;
211 }
212 OHOS::Bluetooth::BluetoothHiTrace::BluetoothStartAsyncTrace("A2DP_SRC_CONNECT", 1);
213 int32_t result = pimpl->a2dpSrcService_->Connect(device);
214 OHOS::Bluetooth::BluetoothHiTrace::BluetoothFinishAsyncTrace("A2DP_SRC_CONNECT", 1);
215 return result;
216 }
217
Disconnect(const RawAddress & device)218 int32_t BluetoothA2dpSourceServer::Disconnect(const RawAddress &device)
219 {
220 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
221 if (PermissionUtils::VerifyDiscoverBluetoothPermission() == PERMISSION_DENIED) {
222 HILOGE("Disconnect error, check permission failed");
223 return BT_ERR_SYSTEM_PERMISSION_FAILED;
224 }
225 return pimpl->a2dpSrcService_->Disconnect(device);
226 }
227
GetDeviceState(const RawAddress & device,int & state)228 int BluetoothA2dpSourceServer::GetDeviceState(const RawAddress &device, int &state)
229 {
230 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
231 if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
232 HILOGE("false, check permission failed");
233 return RET_NO_SUPPORT;
234 }
235 state = pimpl->a2dpSrcService_->GetDeviceState(device);
236 return NO_ERROR;
237 }
238
GetDevicesByStates(const std::vector<int32_t> & states,std::vector<RawAddress> & rawAddrs)239 int BluetoothA2dpSourceServer::GetDevicesByStates(const std::vector<int32_t> &states, std::vector<RawAddress> &rawAddrs)
240 {
241 HILOGI("starts");
242 if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
243 HILOGE("false, check permission failed");
244 return RET_NO_SUPPORT;
245 }
246 std::vector<int> tmpStates;
247 for (int32_t state : states) {
248 HILOGI("state = %{public}d", state);
249 tmpStates.push_back((int)state);
250 }
251
252 rawAddrs = pimpl->a2dpSrcService_->GetDevicesByStates(tmpStates);
253 return NO_ERROR;
254 }
255
GetPlayingState(const RawAddress & device,int & state)256 int32_t BluetoothA2dpSourceServer::GetPlayingState(const RawAddress &device, int &state)
257 {
258 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
259 if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
260 HILOGE("false, check permission failed");
261 return BT_ERR_SYSTEM_PERMISSION_FAILED;
262 }
263 int ret = pimpl->a2dpSrcService_->GetPlayingState(device, state);
264 if (ret != NO_ERROR) {
265 return BT_ERR_INTERNAL_ERROR;
266 }
267 return NO_ERROR;
268 }
269
SetConnectStrategy(const RawAddress & device,int strategy)270 int BluetoothA2dpSourceServer::SetConnectStrategy(const RawAddress &device, int strategy)
271 {
272 HILOGI("addr: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
273 return pimpl->a2dpSrcService_->SetConnectStrategy(device, strategy);
274 }
275
GetConnectStrategy(const RawAddress & device,int & strategy)276 int BluetoothA2dpSourceServer::GetConnectStrategy(const RawAddress &device, int &strategy)
277 {
278 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
279 strategy = pimpl->a2dpSrcService_->GetConnectStrategy(device);
280 return NO_ERROR;
281 }
282
SetActiveSinkDevice(const RawAddress & device)283 int BluetoothA2dpSourceServer::SetActiveSinkDevice(const RawAddress &device)
284 {
285 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
286 return pimpl->a2dpSrcService_->SetActiveSinkDevice(device);
287 }
288
GetActiveSinkDevice()289 RawAddress BluetoothA2dpSourceServer::GetActiveSinkDevice()
290 {
291 HILOGI("starts");
292 return pimpl->a2dpSrcService_->GetActiveSinkDevice();
293 }
294
GetCodecStatus(const RawAddress & device)295 BluetoothA2dpCodecStatus BluetoothA2dpSourceServer::GetCodecStatus(const RawAddress &device)
296 {
297 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
298 bluetooth::RawAddress addr(device.GetAddress());
299 bluetooth::A2dpSrcCodecStatus ret;
300 BluetoothA2dpCodecStatus codeStatus;
301 BluetoothA2dpCodecInfo serviceInfo;
302 ret = pimpl->a2dpSrcService_->GetCodecStatus(addr);
303
304 codeStatus.codecInfo.codecPriority = ret.codecInfo.codecPriority;
305 codeStatus.codecInfo.codecType = ret.codecInfo.codecType;
306 codeStatus.codecInfo.sampleRate = ret.codecInfo.sampleRate;
307 codeStatus.codecInfo.bitsPerSample = ret.codecInfo.bitsPerSample;
308 codeStatus.codecInfo.channelMode = ret.codecInfo.channelMode;
309 codeStatus.codecInfo.codecSpecific1 = ret.codecInfo.codecSpecific1;
310 codeStatus.codecInfo.codecSpecific2 = ret.codecInfo.codecSpecific2;
311 codeStatus.codecInfo.codecSpecific3 = ret.codecInfo.codecSpecific3;
312 codeStatus.codecInfo.codecSpecific4 = ret.codecInfo.codecSpecific4;
313
314 for (auto it = ret.codecInfoConfirmedCap.begin(); it != ret.codecInfoConfirmedCap.end(); it++) {
315 serviceInfo.codecPriority = it->codecPriority;
316 serviceInfo.codecType = it->codecType;
317 serviceInfo.sampleRate = it->sampleRate;
318 serviceInfo.bitsPerSample = it->bitsPerSample;
319 serviceInfo.channelMode = it->channelMode;
320 serviceInfo.codecSpecific1 = it->codecSpecific1;
321 serviceInfo.codecSpecific2 = it->codecSpecific2;
322 serviceInfo.codecSpecific3 = it->codecSpecific3;
323 serviceInfo.codecSpecific4 = it->codecSpecific4;
324 codeStatus.codecInfoConfirmCap.push_back(serviceInfo);
325 }
326
327 for (auto it = ret.codecInfoLocalCap.begin(); it != ret.codecInfoLocalCap.end(); it++) {
328 serviceInfo.codecPriority = it->codecPriority;
329 serviceInfo.codecType = it->codecType;
330 serviceInfo.sampleRate = it->sampleRate;
331 serviceInfo.bitsPerSample = it->bitsPerSample;
332 serviceInfo.channelMode = it->channelMode;
333 serviceInfo.codecSpecific1 = it->codecSpecific1;
334 serviceInfo.codecSpecific2 = it->codecSpecific2;
335 serviceInfo.codecSpecific3 = it->codecSpecific3;
336 serviceInfo.codecSpecific4 = it->codecSpecific4;
337 codeStatus.codecInfoLocalCap.push_back(serviceInfo);
338 }
339
340 return codeStatus;
341 }
342
SetCodecPreference(const RawAddress & device,const BluetoothA2dpCodecInfo & info)343 int BluetoothA2dpSourceServer::SetCodecPreference(const RawAddress &device, const BluetoothA2dpCodecInfo &info)
344 {
345 HILOGI("BluetoothA2dpSourceServer::SetCodecPreference starts, codecPriority = %{public}u,"
346 "codecPriority = %{public}u, sampleRate = %{public}u, bitsPerSample = %{public}d, "
347 "channelMode = %{public}d, codecSpecific1 = %{public}llu, codecSpecific2 = %{public}llu, "
348 "codecSpecific3 = %{public}llu, codecSpecific4 = %{public}llu",
349 info.codecPriority, info.codecType, info.sampleRate, info.bitsPerSample, info.channelMode,
350 (unsigned long long)info.codecSpecific1, (unsigned long long)info.codecSpecific2,
351 (unsigned long long)info.codecSpecific3, (unsigned long long)info.codecSpecific4);
352 bluetooth::A2dpSrcCodecInfo setInfo;
353
354 setInfo.bitsPerSample = info.bitsPerSample;
355 setInfo.channelMode = info.channelMode;
356 setInfo.codecPriority = info.codecPriority;
357 setInfo.codecType = info.codecType;
358 setInfo.sampleRate = info.sampleRate;
359 setInfo.codecSpecific1 = info.codecSpecific1;
360 setInfo.codecSpecific2 = info.codecSpecific2;
361 setInfo.codecSpecific3 = info.codecSpecific3;
362 setInfo.codecSpecific4 = info.codecSpecific4;
363
364 return pimpl->a2dpSrcService_->SetCodecPreference(device, setInfo);
365 }
366
SwitchOptionalCodecs(const RawAddress & device,bool isEnable)367 void BluetoothA2dpSourceServer::SwitchOptionalCodecs(const RawAddress &device, bool isEnable)
368 {
369 HILOGI("addr: %{public}s, isEnable = %{public}d", GET_ENCRYPT_ADDR(device), isEnable);
370 pimpl->a2dpSrcService_->SwitchOptionalCodecs(device, isEnable);
371 }
372
GetOptionalCodecsSupportState(const RawAddress & device)373 int BluetoothA2dpSourceServer::GetOptionalCodecsSupportState(const RawAddress &device)
374 {
375 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
376 return pimpl->a2dpSrcService_->GetOptionalCodecsSupportState(device);
377 }
378
StartPlaying(const RawAddress & device)379 int BluetoothA2dpSourceServer::StartPlaying(const RawAddress &device)
380 {
381 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
382 return pimpl->a2dpSrcService_->StartPlaying(device);
383 }
384
SuspendPlaying(const RawAddress & device)385 int BluetoothA2dpSourceServer::SuspendPlaying(const RawAddress &device)
386 {
387 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
388 return pimpl->a2dpSrcService_->SuspendPlaying(device);
389 }
390
StopPlaying(const RawAddress & device)391 int BluetoothA2dpSourceServer::StopPlaying(const RawAddress &device)
392 {
393 HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
394 return pimpl->a2dpSrcService_->StopPlaying(device);
395 }
396
WriteFrame(const uint8_t * data,uint32_t size)397 int BluetoothA2dpSourceServer::WriteFrame(const uint8_t *data, uint32_t size)
398 {
399 HILOGI("size = %{public}u", size);
400 return pimpl->a2dpSrcService_->WriteFrame(data, size);
401 }
402
GetRenderPosition(uint16_t & delayValue,uint16_t & sendDataSize,uint32_t & timeStamp)403 void BluetoothA2dpSourceServer::GetRenderPosition(uint16_t &delayValue, uint16_t &sendDataSize, uint32_t &timeStamp)
404 {
405 HILOGI("starts");
406 pimpl->a2dpSrcService_->GetRenderPosition(delayValue, sendDataSize, timeStamp);
407 HILOGI("delayValue = %{public}hu, sendDataSize = %{public}hu, timeStamp = %{public}u", delayValue, sendDataSize,
408 timeStamp);
409 }
410 } // namespace Bluetooth
411 } // namespace OHOS