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 #include <mutex>
16 #include "bluetooth_def.h"
17 #include "bluetooth_avrcp_tg_server.h"
18 #include "bluetooth_log.h"
19 #include "bluetooth_utils.h"
20 #include "interface_adapter_manager.h"
21 #include "interface_profile.h"
22 #include "interface_profile_avrcp_tg.h"
23 #include "interface_profile_manager.h"
24 #include "remote_observer_list.h"
25 #include "permission_utils.h"
26
27
28 namespace OHOS {
29 namespace Bluetooth {
30 using namespace OHOS::bluetooth;
31
32 struct BluetoothAvrcpTgServer::impl {
33 public:
34 class SysStsObserverImpl : public ISystemStateObserver {
35 public:
SysStsObserverImpl(BluetoothAvrcpTgServer::impl * impl)36 explicit SysStsObserverImpl(BluetoothAvrcpTgServer::impl *impl) : impl_(impl) {}
~SysStsObserverImpl()37 virtual ~SysStsObserverImpl() {}
38
OnSystemStateChange(const BTSystemState state)39 void OnSystemStateChange(const BTSystemState state) override
40 {
41 impl_->OnSystemStateChange(state);
42 }
43
44 private:
45 BluetoothAvrcpTgServer::impl *impl_;
46 };
47 class ObserverImpl : public IProfileAvrcpTg::IObserver {
48 public:
ObserverImpl(BluetoothAvrcpTgServer::impl * impl)49 explicit ObserverImpl(BluetoothAvrcpTgServer::impl *impl) : impl_(impl) {}
~ObserverImpl()50 virtual ~ObserverImpl() {}
51
OnConnectionStateChanged(const RawAddress & rawAddr,int state)52 void OnConnectionStateChanged(const RawAddress &rawAddr, int state) override
53 {
54 impl_->OnConnectionStateChanged(rawAddr, state);
55 }
56
57 private:
58 BluetoothAvrcpTgServer::impl *impl_;
59 };
60
implOHOS::Bluetooth::BluetoothAvrcpTgServer::impl61 impl()
62 {
63 HILOGI("start.");
64
65 auto svManager = IProfileManager::GetInstance();
66 service_ = static_cast<IProfileAvrcpTg *>(svManager->GetProfileService(PROFILE_NAME_AVRCP_TG));
67 if (service_ != nullptr) {
68 observer_ = std::make_unique<ObserverImpl>(this);
69 service_->RegisterObserver(observer_.get());
70 }
71
72 sysObserver_ = std::make_unique<SysStsObserverImpl>(this);
73 IAdapterManager::GetInstance()->RegisterSystemStateObserver(*sysObserver_);
74 }
75
~implOHOS::Bluetooth::BluetoothAvrcpTgServer::impl76 ~impl()
77 {
78 HILOGI("start.");
79
80 auto svManager = IProfileManager::GetInstance();
81 service_ = static_cast<IProfileAvrcpTg *>(svManager->GetProfileService(PROFILE_NAME_AVRCP_TG));
82 if (service_ != nullptr) {
83 service_->UnregisterObserver();
84 observer_ = nullptr;
85 service_ = nullptr;
86 }
87
88 IAdapterManager::GetInstance()->DeregisterSystemStateObserver(*sysObserver_);
89 sysObserver_ = nullptr;
90 }
91
IsEnabledOHOS::Bluetooth::BluetoothAvrcpTgServer::impl92 bool IsEnabled()
93 {
94 HILOGI("start.");
95
96 auto servManager = IProfileManager::GetInstance();
97 service_ = static_cast<IProfileAvrcpTg *>(servManager->GetProfileService(PROFILE_NAME_AVRCP_TG));
98
99 return (service_ != nullptr && service_->IsEnabled());
100 }
101
OnSystemStateChangeOHOS::Bluetooth::BluetoothAvrcpTgServer::impl102 void OnSystemStateChange(const BTSystemState state)
103 {
104 HILOGI("start.");
105
106 std::lock_guard<std::mutex> lock(serviceMutex_);
107
108 switch (state) {
109 case BTSystemState::ON: {
110 auto svManager = IProfileManager::GetInstance();
111 service_ = static_cast<IProfileAvrcpTg *>(svManager->GetProfileService(PROFILE_NAME_AVRCP_TG));
112 if (service_ != nullptr) {
113 observer_ = std::make_unique<ObserverImpl>(this);
114 service_->RegisterObserver(observer_.get());
115 }
116 break;
117 }
118 case BTSystemState::OFF:
119 /// FALL THROUGH
120 default:
121 if (service_ != nullptr) {
122 service_->UnregisterObserver();
123 observer_ = nullptr;
124 service_ = nullptr;
125 }
126 break;
127 }
128 }
129
OnConnectionStateChangedOHOS::Bluetooth::BluetoothAvrcpTgServer::impl130 void OnConnectionStateChanged(const RawAddress &rawAddr, int state)
131 {
132 HILOGI("res: %{public}s, state: %{public}d.", GET_ENCRYPT_AVRCP_ADDR(rawAddr), state);
133 std::lock_guard<std::mutex> lock(observerMutex_);
134
135 observers_.ForEach([rawAddr, state](IBluetoothAvrcpTgObserver *observer) {
136 observer->OnConnectionStateChanged(rawAddr, static_cast<int32_t>(state));
137 });
138 }
139
140 std::mutex serviceMutex_;
141 IProfileAvrcpTg *service_;
142
143 std::mutex observerMutex_;
144 RemoteObserverList<IBluetoothAvrcpTgObserver> observers_;
145
146 std::unique_ptr<ObserverImpl> observer_;
147 std::unique_ptr<SysStsObserverImpl> sysObserver_;
148 };
149
BluetoothAvrcpTgServer()150 BluetoothAvrcpTgServer::BluetoothAvrcpTgServer()
151 {
152 HILOGI("start.");
153
154 pimpl = std::make_unique<impl>();
155 }
156
~BluetoothAvrcpTgServer()157 BluetoothAvrcpTgServer::~BluetoothAvrcpTgServer()
158 {
159 pimpl = nullptr;
160 }
161
RegisterObserver(const sptr<IBluetoothAvrcpTgObserver> & observer)162 void BluetoothAvrcpTgServer::RegisterObserver(const sptr<IBluetoothAvrcpTgObserver> &observer)
163 {
164 HILOGI("start.");
165
166 std::lock_guard<std::mutex> lock(pimpl->observerMutex_);
167
168 if (observer == nullptr) {
169 HILOGI("observer is NULL.");
170 return ;
171 }
172 auto func = std::bind(&BluetoothAvrcpTgServer::UnregisterObserver, this, std::placeholders::_1);
173 pimpl->observers_.Register(observer, func);
174 HILOGI("end.");
175
176 return ;
177 }
178
UnregisterObserver(const sptr<IBluetoothAvrcpTgObserver> & observer)179 void BluetoothAvrcpTgServer::UnregisterObserver(const sptr<IBluetoothAvrcpTgObserver> &observer)
180 {
181 HILOGI("start.");
182
183 std::lock_guard<std::mutex> lock(pimpl->observerMutex_);
184
185 if (observer == nullptr) {
186 HILOGI("observer is NULL.");
187 return;
188 }
189 pimpl->observers_.Deregister(observer);
190 HILOGI("end.");
191
192 return;
193 }
194
SetActiveDevice(const BluetoothRawAddress & addr)195 void BluetoothAvrcpTgServer::SetActiveDevice(const BluetoothRawAddress &addr)
196 {
197 HILOGI("address: %{public}s", GetEncryptAddr(addr.GetAddress()).c_str());
198
199 if (pimpl->IsEnabled()) {
200 pimpl->service_->SetActiveDevice(addr);
201 } else {
202 HILOGE("service is null or disable ");
203 }
204 HILOGI("end.");
205 }
206
Connect(const BluetoothRawAddress & addr)207 int32_t BluetoothAvrcpTgServer::Connect(const BluetoothRawAddress &addr)
208 {
209 HILOGI("address: %{public}s", GetEncryptAddr(addr.GetAddress()).c_str());
210 if (PermissionUtils::VerifyDiscoverBluetoothPermission() == PERMISSION_DENIED) {
211 HILOGE("Connect error, check permission failed");
212 return BT_FAILURE;
213 }
214 int32_t result = 0;
215
216 if (pimpl->IsEnabled()) {
217 result = pimpl->service_->Connect(addr);
218 } else {
219 HILOGE("service is null or disable ");
220 }
221 HILOGI("end.");
222
223 return result;
224 }
225
Disconnect(const BluetoothRawAddress & addr)226 int32_t BluetoothAvrcpTgServer::Disconnect(const BluetoothRawAddress &addr)
227 {
228 HILOGI("address: %{public}s", GetEncryptAddr(addr.GetAddress()).c_str());
229
230 int32_t result = 0;
231
232 if (pimpl->IsEnabled()) {
233 result = pimpl->service_->Disconnect(addr);
234 } else {
235 HILOGE("service is null or disable ");
236 }
237 HILOGI("end.");
238
239 return result;
240 }
241
GetConnectedDevices()242 std::vector<BluetoothRawAddress> BluetoothAvrcpTgServer::GetConnectedDevices()
243 {
244 HILOGI("start.");
245 std::vector<BluetoothRawAddress> results;
246 if (!pimpl->IsEnabled()) {
247 HILOGE("service is null or disable ");
248 return results;
249 }
250
251 std::vector<RawAddress> devices;
252 devices = pimpl->service_->GetConnectedDevices();
253 for (auto device : devices) {
254 BluetoothRawAddress rawAddr = BluetoothRawAddress(device);
255 results.emplace_back(rawAddr);
256 }
257 HILOGI("end.");
258 return results;
259 }
260
GetDevicesByStates(const std::vector<int32_t> & states)261 std::vector<BluetoothRawAddress> BluetoothAvrcpTgServer::GetDevicesByStates(const std::vector<int32_t> &states)
262 {
263 HILOGI("start.");
264
265 std::vector<BluetoothRawAddress> results;
266
267 if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
268 HILOGE("false, check permission failed");
269 return results;
270 }
271 if (!pimpl->IsEnabled()) {
272 HILOGE("service is null or disable ");
273 return results;
274 }
275
276 std::vector<RawAddress> devices;
277 std::vector<int> convertStates;
278 for (auto state : states) {
279 HILOGI("state = %{public}d", state);
280 convertStates.push_back(static_cast<int>(state));
281 }
282
283 devices = pimpl->service_->GetDevicesByStates(convertStates);
284 for (auto device : devices) {
285 BluetoothRawAddress rawAddr = BluetoothRawAddress(device);
286 results.emplace_back(rawAddr);
287 }
288 HILOGI("end.");
289
290 return results;
291 }
292
GetDeviceState(const BluetoothRawAddress & addr)293 int32_t BluetoothAvrcpTgServer::GetDeviceState(const BluetoothRawAddress &addr)
294 {
295 HILOGI("address: %{public}s", GetEncryptAddr(addr.GetAddress()).c_str());
296 if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
297 HILOGE("false, check permission failed");
298 return BT_FAILURE;
299 }
300 int32_t result = 0;
301
302 if (pimpl->IsEnabled()) {
303 result = pimpl->service_->GetDeviceState(addr);
304 } else {
305 HILOGE("service is null or disable ");
306 }
307 HILOGI("end.");
308
309 return result;
310 }
311
NotifyPlaybackStatusChanged(int32_t playStatus,int32_t playbackPos)312 void BluetoothAvrcpTgServer::NotifyPlaybackStatusChanged(int32_t playStatus, int32_t playbackPos)
313 {
314 HILOGI("playStatus: %{public}d, playbackPos: %{public}d", playStatus, playbackPos);
315
316 if (!pimpl->IsEnabled()) {
317 HILOGE("service is null or disable ");
318 return;
319 }
320
321 pimpl->service_->NotifyPlaybackStatusChanged(static_cast<uint8_t>(playStatus),
322 static_cast<uint32_t>(playbackPos));
323 HILOGI("end.");
324 }
325
NotifyTrackChanged(int64_t uid,int32_t playbackPos)326 void BluetoothAvrcpTgServer::NotifyTrackChanged(int64_t uid, int32_t playbackPos)
327 {
328 HILOGI("uid: %{public}jd, playbackPos: %{public}d", uid, playbackPos);
329
330 if (!pimpl->IsEnabled()) {
331 HILOGE("service is null or disable ");
332 return;
333 }
334
335 pimpl->service_->NotifyTrackChanged(static_cast<uint64_t>(uid), static_cast<uint32_t>(playbackPos));
336 HILOGI("end.");
337 }
338
NotifyTrackReachedEnd(int32_t playbackPos)339 void BluetoothAvrcpTgServer::NotifyTrackReachedEnd(int32_t playbackPos)
340 {
341 HILOGI("playbackPos: %{public}d", playbackPos);
342
343 if (!pimpl->IsEnabled()) {
344 HILOGE("service is null or disable ");
345 return;
346 }
347
348 pimpl->service_->NotifyTrackReachedEnd(static_cast<uint32_t>(playbackPos));
349 HILOGI("end.");
350 }
351
NotifyTrackReachedStart(int32_t playbackPos)352 void BluetoothAvrcpTgServer::NotifyTrackReachedStart(int32_t playbackPos)
353 {
354 HILOGI("playbackPos: %{public}d", playbackPos);
355
356 if (!pimpl->IsEnabled()) {
357 HILOGE("service is null or disable ");
358 return;
359 }
360
361 pimpl->service_->NotifyTrackReachedStart(static_cast<uint32_t>(playbackPos));
362 HILOGI("end.");
363 }
364
NotifyPlaybackPosChanged(int32_t playbackPos)365 void BluetoothAvrcpTgServer::NotifyPlaybackPosChanged(int32_t playbackPos)
366 {
367 HILOGI("playbackPos: %{public}d", playbackPos);
368
369 if (!pimpl->IsEnabled()) {
370 HILOGE("service is null or disable ");
371 return;
372 }
373
374 pimpl->service_->NotifyPlaybackPosChanged(static_cast<uint32_t>(playbackPos));
375 HILOGI("end.");
376 }
377
NotifyPlayerAppSettingChanged(const std::vector<int32_t> & attributes,const std::vector<int32_t> & values)378 void BluetoothAvrcpTgServer::NotifyPlayerAppSettingChanged(const std::vector<int32_t> &attributes,
379 const std::vector<int32_t> &values)
380 {
381 HILOGI("start.");
382
383 if (!pimpl->IsEnabled()) {
384 HILOGE("service is null or disable ");
385 return;
386 }
387
388 std::deque<uint8_t> attrs;
389 std::deque<uint8_t> vals;
390
391 for (auto attribute : attributes) {
392 HILOGI("attributes = %{public}d", attribute);
393 attrs.push_back(attribute);
394 }
395 for (auto value : values) {
396 HILOGI("values = %{public}d", value);
397 vals.push_back(value);
398 }
399
400 pimpl->service_->NotifyPlayerAppSettingChanged(attrs, vals);
401 HILOGI("end.");
402 }
403
NotifyNowPlayingContentChanged()404 void BluetoothAvrcpTgServer::NotifyNowPlayingContentChanged()
405 {
406 HILOGI("start.");
407
408 if (!pimpl->IsEnabled()) {
409 HILOGE("service is null or disable ");
410 return;
411 }
412
413 pimpl->service_->NotifyNowPlayingContentChanged();
414 HILOGI("end.");
415 }
416
NotifyAvailablePlayersChanged()417 void BluetoothAvrcpTgServer::NotifyAvailablePlayersChanged()
418 {
419 HILOGI("start.");
420
421 if (!pimpl->IsEnabled()) {
422 HILOGE("service is null or disable ");
423 return;
424 }
425
426 pimpl->service_->NotifyAvailablePlayersChanged();
427 HILOGI("end.");
428 }
429
NotifyAddressedPlayerChanged(int32_t playerId,int32_t uidCounter)430 void BluetoothAvrcpTgServer::NotifyAddressedPlayerChanged(int32_t playerId, int32_t uidCounter)
431 {
432 HILOGI("playerId: %{public}d, uidCounter: %{public}d", playerId, uidCounter);
433
434 if (!pimpl->IsEnabled()) {
435 HILOGE("service is null or disable ");
436 return;
437 }
438
439 pimpl->service_->NotifyAddressedPlayerChanged(static_cast<uint32_t>(playerId), static_cast<uint32_t>(uidCounter));
440 HILOGI("end.");
441 }
442
NotifyUidChanged(int32_t uidCounter)443 void BluetoothAvrcpTgServer::NotifyUidChanged(int32_t uidCounter)
444 {
445 HILOGI("uidCounter: %{public}d", uidCounter);
446
447 if (!pimpl->IsEnabled()) {
448 HILOGE("service is null or disable ");
449 return;
450 }
451
452 pimpl->service_->NotifyUidChanged(static_cast<uint32_t>(uidCounter));
453 HILOGI("end.");
454 }
455
NotifyVolumeChanged(int32_t volume)456 void BluetoothAvrcpTgServer::NotifyVolumeChanged(int32_t volume)
457 {
458 HILOGI("volume: %{public}d", volume);
459
460 if (!pimpl->IsEnabled()) {
461 HILOGE("service is null or disable ");
462 return;
463 }
464
465 pimpl->service_->NotifyVolumeChanged(static_cast<uint8_t>(volume));
466 HILOGI("end.");
467 }
468 } // namespace Bluetooth
469 } // namespace OHOS