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 <list>
17 #include <memory>
18 #include <mutex>
19
20 #include "bluetooth_def.h"
21 #include "bluetooth_avrcp_tg_proxy.h"
22 #include "bluetooth_avrcp_tg_observer_stub.h"
23 #include "bluetooth_host.h"
24 #include "bluetooth_host_proxy.h"
25 #include "bluetooth_load_system_ability.h"
26 #include "bluetooth_log.h"
27 #include "bluetooth_utils.h"
28 #include "bluetooth_observer_list.h"
29 #include "iservice_registry.h"
30 #include "raw_address.h"
31 #include "system_ability_definition.h"
32 #include "bluetooth_avrcp_tg.h"
33
34 namespace OHOS {
35 namespace Bluetooth {
36 std::mutex g_avrcpTgMutex;
37 struct AvrcpTarget::impl {
38 public:
39 class ObserverImpl : public BluetoothAvrcpTgObserverStub {
40 public:
ObserverImpl(AvrcpTarget::impl * impl)41 explicit ObserverImpl(AvrcpTarget::impl *impl) : impl_(impl)
42 {}
43 ~ObserverImpl() override = default;
44
OnConnectionStateChanged(const BluetoothRawAddress & addr,int32_t state)45 void OnConnectionStateChanged(const BluetoothRawAddress &addr, int32_t state) override
46 {
47 HILOGD("enter, address: %{public}s, state: %{public}d", GetEncryptAddr(addr.GetAddress()).c_str(), state);
48 BluetoothRemoteDevice device(addr.GetAddress(), BTTransport::ADAPTER_BREDR);
49 impl_->OnConnectionStateChanged(device, static_cast<int>(state));
50
51 return;
52 }
53
54 private:
55 AvrcpTarget::impl *impl_;
56 };
57
58 class AvrcpTgDeathRecipient final : public IRemoteObject::DeathRecipient {
59 public:
AvrcpTgDeathRecipient(AvrcpTarget::impl & avrcpTgServer)60 explicit AvrcpTgDeathRecipient(AvrcpTarget::impl &avrcpTgServer) : avrcpTgServer_(avrcpTgServer) {};
61 ~AvrcpTgDeathRecipient() final = default;
62 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(AvrcpTgDeathRecipient);
63
OnRemoteDied(const wptr<IRemoteObject> & remote)64 void OnRemoteDied(const wptr<IRemoteObject> &remote) final
65 {
66 HILOGI("starts");
67 std::lock_guard<std::mutex> lock(g_avrcpTgMutex);
68 if (!avrcpTgServer_.proxy_) {
69 return;
70 }
71 avrcpTgServer_.proxy_ = nullptr;
72 }
73
74 private:
75 AvrcpTarget::impl &avrcpTgServer_;
76 };
77
implOHOS::Bluetooth::AvrcpTarget::impl78 impl()
79 {
80 if (proxy_) {
81 return;
82 }
83 BluetootLoadSystemAbility::GetInstance().RegisterNotifyMsg(PROFILE_ID_AVRCP_TG);
84 if (!BluetootLoadSystemAbility::GetInstance().HasSubscribedBluetoothSystemAbility()) {
85 BluetootLoadSystemAbility::GetInstance().SubScribeBluetoothSystemAbility();
86 return;
87 }
88 InitAvrcpTgProxy();
89 }
90
~implOHOS::Bluetooth::AvrcpTarget::impl91 ~impl()
92 {
93 HILOGI("enter");
94 if (proxy_ != nullptr) {
95 proxy_->UnregisterObserver(observer_);
96 proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
97 }
98 }
99
InitAvrcpTgProxyOHOS::Bluetooth::AvrcpTarget::impl100 bool InitAvrcpTgProxy(void)
101 {
102 std::lock_guard<std::mutex> lock(g_avrcpTgMutex);
103 if (proxy_) {
104 return true;
105 }
106 proxy_ = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
107 if (!proxy_) {
108 HILOGE("get AvrcpTarget proxy failed");
109 return false;
110 }
111
112 observer_ = new (std::nothrow) ObserverImpl(this);
113 if (observer_ != nullptr) {
114 proxy_->RegisterObserver(observer_);
115 }
116
117 deathRecipient_ = new AvrcpTgDeathRecipient(*this);
118 if (deathRecipient_ != nullptr) {
119 proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
120 }
121 return true;
122 }
123
IsEnabledOHOS::Bluetooth::AvrcpTarget::impl124 bool IsEnabled(void)
125 {
126 HILOGI("enter");
127
128 return (proxy_ != nullptr && !BluetoothHost::GetDefaultHost().IsBtDiscovering());
129 }
130
OnConnectionStateChangedOHOS::Bluetooth::AvrcpTarget::impl131 void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state)
132 {
133 HILOGI("enter, device: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state);
134 std::lock_guard<std::mutex> lock(observerMutex_);
135 observers_.ForEach([device, state](std::shared_ptr<IObserver> observer) {
136 observer->OnConnectionStateChanged(device, state);
137 });
138 }
139
140 std::mutex observerMutex_;
141 sptr<IBluetoothAvrcpTg> proxy_;
142 BluetoothObserverList<AvrcpTarget::IObserver> observers_;
143 sptr<ObserverImpl> observer_;
144 sptr<AvrcpTgDeathRecipient> deathRecipient_;
145 };
146
GetProfile(void)147 AvrcpTarget *AvrcpTarget::GetProfile(void)
148 {
149 HILOGI("enter");
150
151 static AvrcpTarget instance;
152
153 return &instance;
154 }
155
Init()156 void AvrcpTarget::Init()
157 {
158 if (!pimpl) {
159 HILOGE("fails: no pimpl");
160 return;
161 }
162 if (!pimpl->InitAvrcpTgProxy()) {
163 HILOGE("AvrcpTarget proxy is nullptr");
164 return;
165 }
166 }
167
168 /******************************************************************
169 * REGISTER / UNREGISTER OBSERVER *
170 ******************************************************************/
171
RegisterObserver(AvrcpTarget::IObserver * observer)172 void AvrcpTarget::RegisterObserver(AvrcpTarget::IObserver *observer)
173 {
174 HILOGI("enter");
175
176 std::lock_guard<std::mutex> lock(pimpl->observerMutex_);
177 std::shared_ptr<IObserver> observerPtr(observer, [](IObserver *) {});
178 pimpl->observers_.Register(observerPtr);
179 }
180
UnregisterObserver(AvrcpTarget::IObserver * observer)181 void AvrcpTarget::UnregisterObserver(AvrcpTarget::IObserver *observer)
182 {
183 HILOGI("enter");
184
185 std::lock_guard<std::mutex> lock(pimpl->observerMutex_);
186
187 std::shared_ptr<IObserver> observerPtr(observer, [](IObserver *) {});
188 pimpl->observers_.Deregister(observerPtr);
189 }
190
191 /******************************************************************
192 * CONNECTION *
193 ******************************************************************/
194
SetActiveDevice(const BluetoothRemoteDevice & device)195 void AvrcpTarget::SetActiveDevice(const BluetoothRemoteDevice &device)
196 {
197 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
198 if (!IS_BT_ENABLED()) {
199 HILOGE("bluetooth is off.");
200 return;
201 }
202
203 if (pimpl == nullptr || !pimpl->proxy_) {
204 HILOGE("pimpl or avrcpTarget proxy is nullptr");
205 return;
206 }
207
208 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
209 pimpl->proxy_->SetActiveDevice(rawAddr);
210 }
211
GetConnectedDevices(void)212 std::vector<BluetoothRemoteDevice> AvrcpTarget::GetConnectedDevices(void)
213 {
214 if (!IS_BT_ENABLED()) {
215 HILOGE("bluetooth is off.");
216 return std::vector<BluetoothRemoteDevice>();
217 }
218
219 if (pimpl == nullptr || !pimpl->proxy_) {
220 HILOGE("pimpl or avrcpTarget proxy is nullptr");
221 return std::vector<BluetoothRemoteDevice>();
222 }
223
224 std::vector<BluetoothRemoteDevice> devices;
225 std::vector<BluetoothRawAddress> rawAddrs = pimpl->proxy_->GetConnectedDevices();
226 for (auto rawAddr : rawAddrs) {
227 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
228 devices.push_back(device);
229 }
230 return devices;
231 }
232
GetDevicesByStates(std::vector<int> states)233 std::vector<BluetoothRemoteDevice> AvrcpTarget::GetDevicesByStates(std::vector<int> states)
234 {
235 if (!IS_BT_ENABLED()) {
236 HILOGE("bluetooth is off.");
237 return std::vector<BluetoothRemoteDevice>();
238 }
239
240 if (pimpl == nullptr || !pimpl->proxy_) {
241 HILOGE("pimpl or avrcpTarget proxy is nullptr");
242 return std::vector<BluetoothRemoteDevice>();
243 }
244
245 std::vector<int32_t> convertStates;
246 for (auto state : states) {
247 convertStates.push_back(static_cast<int32_t>(state));
248 }
249
250 std::vector<BluetoothRemoteDevice> devices;
251 std::vector<BluetoothRawAddress> rawAddrs = pimpl->proxy_->GetDevicesByStates(convertStates);
252 for (auto rawAddr : rawAddrs) {
253 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
254 devices.push_back(device);
255 }
256
257 return devices;
258 }
259
GetDeviceState(const BluetoothRemoteDevice & device)260 int AvrcpTarget::GetDeviceState(const BluetoothRemoteDevice &device)
261 {
262 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
263
264 if (!IS_BT_ENABLED()) {
265 HILOGE("bluetooth is off.");
266 return static_cast<int32_t>(BTConnectState::DISCONNECTED);
267 }
268
269 if (pimpl == nullptr || !pimpl->proxy_) {
270 HILOGE("pimpl or avrcpTarget proxy is nullptr");
271 return static_cast<int32_t>(BTConnectState::DISCONNECTED);
272 }
273
274 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
275 int32_t result = pimpl->proxy_->GetDeviceState(rawAddr);
276 return static_cast<int>(result);
277 }
278
Connect(const BluetoothRemoteDevice & device)279 bool AvrcpTarget::Connect(const BluetoothRemoteDevice &device)
280 {
281 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
282
283 if (!IS_BT_ENABLED()) {
284 HILOGE("bluetooth is off.");
285 return RET_BAD_STATUS;
286 }
287
288 if (pimpl == nullptr || !pimpl->proxy_) {
289 HILOGE("pimpl or avrcpTarget proxy is nullptr");
290 return RET_BAD_STATUS;
291 }
292
293 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
294 int result = pimpl->proxy_->Connect(rawAddr);
295 return result == RET_NO_ERROR;
296 }
297
Disconnect(const BluetoothRemoteDevice & device)298 bool AvrcpTarget::Disconnect(const BluetoothRemoteDevice &device)
299 {
300 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
301
302 if (!IS_BT_ENABLED()) {
303 HILOGE("bluetooth is off.");
304 return RET_BAD_STATUS;
305 }
306
307 if (pimpl == nullptr || !pimpl->proxy_) {
308 HILOGE("pimpl or avrcpTarget proxy is nullptr");
309 return RET_BAD_STATUS;
310 }
311
312 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
313 int result = pimpl->proxy_->Disconnect(rawAddr);
314 return result == RET_NO_ERROR;
315 }
316
317 /******************************************************************
318 * NOTIFICATION *
319 ******************************************************************/
320
NotifyPlaybackStatusChanged(uint8_t playStatus,uint32_t playbackPos)321 void AvrcpTarget::NotifyPlaybackStatusChanged(uint8_t playStatus, uint32_t playbackPos)
322 {
323 HILOGI("enter, playStatus: %{public}d, playbackPos: %{public}d", playStatus, playbackPos);
324 if (!IS_BT_ENABLED()) {
325 HILOGE("bluetooth is off.");
326 return;
327 }
328
329 if (pimpl == nullptr || !pimpl->proxy_) {
330 HILOGE("pimpl or avrcpTarget proxy is nullptr");
331 return;
332 }
333
334 pimpl->proxy_->NotifyPlaybackStatusChanged(static_cast<int32_t>(playStatus), static_cast<int32_t>(playbackPos));
335 }
336
NotifyTrackChanged(uint64_t uid,uint32_t playbackPos)337 void AvrcpTarget::NotifyTrackChanged(uint64_t uid, uint32_t playbackPos)
338 {
339 HILOGI("enter, playbackPos: %{public}d", playbackPos);
340 if (!IS_BT_ENABLED()) {
341 HILOGE("bluetooth is off.");
342 return;
343 }
344
345 if (pimpl == nullptr || !pimpl->proxy_) {
346 HILOGE("pimpl or avrcpTarget proxy is nullptr");
347 return;
348 }
349
350 pimpl->proxy_->NotifyTrackChanged(static_cast<int64_t>(uid), static_cast<int32_t>(playbackPos));
351 }
352
NotifyTrackReachedEnd(uint32_t playbackPos)353 void AvrcpTarget::NotifyTrackReachedEnd(uint32_t playbackPos)
354 {
355 HILOGI("enter, playbackPos: %{public}d", playbackPos);
356 if (!IS_BT_ENABLED()) {
357 HILOGE("bluetooth is off.");
358 return;
359 }
360
361 if (pimpl == nullptr || !pimpl->proxy_) {
362 HILOGE("pimpl or avrcpTarget proxy is nullptr");
363 return;
364 }
365
366 pimpl->proxy_->NotifyTrackReachedEnd(static_cast<int32_t>(playbackPos));
367 }
368
NotifyTrackReachedStart(uint32_t playbackPos)369 void AvrcpTarget::NotifyTrackReachedStart(uint32_t playbackPos)
370 {
371 HILOGI("enter, playbackPos: %{public}d", playbackPos);
372 if (!IS_BT_ENABLED()) {
373 HILOGE("bluetooth is off.");
374 return;
375 }
376
377 if (pimpl == nullptr || !pimpl->proxy_) {
378 HILOGE("pimpl or avrcpTarget proxy is nullptr");
379 return;
380 }
381
382 pimpl->proxy_->NotifyTrackReachedStart(static_cast<int32_t>(playbackPos));
383 }
384
NotifyPlaybackPosChanged(uint32_t playbackPos)385 void AvrcpTarget::NotifyPlaybackPosChanged(uint32_t playbackPos)
386 {
387 HILOGI("enter, playbackPos: %{public}d", playbackPos);
388 if (!IS_BT_ENABLED()) {
389 HILOGE("bluetooth is off.");
390 return;
391 }
392
393 if (pimpl == nullptr || !pimpl->proxy_) {
394 HILOGE("pimpl or avrcpTarget proxy is nullptr");
395 return;
396 }
397
398 pimpl->proxy_->NotifyPlaybackPosChanged(static_cast<int32_t>(playbackPos));
399 }
400
NotifyPlayerAppSettingChanged(const std::vector<uint8_t> & attributes,const std::vector<uint8_t> & values)401 void AvrcpTarget::NotifyPlayerAppSettingChanged(const std::vector<uint8_t> &attributes,
402 const std::vector<uint8_t> &values)
403 {
404 HILOGI("enter");
405 if (!IS_BT_ENABLED()) {
406 HILOGE("bluetooth is off.");
407 return;
408 }
409
410 if (pimpl == nullptr || !pimpl->proxy_) {
411 HILOGE("pimpl or avrcpTarget proxy is nullptr");
412 return;
413 }
414
415 std::vector<int32_t> attrs;
416 for (auto attribute : attributes) {
417 attrs.push_back(attribute);
418 }
419 std::vector<int32_t> vals;
420 for (auto value : values) {
421 vals.push_back(value);
422 }
423
424 pimpl->proxy_->NotifyPlayerAppSettingChanged(attrs, vals);
425 }
426
NotifyNowPlayingContentChanged(void)427 void AvrcpTarget::NotifyNowPlayingContentChanged(void)
428 {
429 HILOGI("enter");
430 if (!IS_BT_ENABLED()) {
431 HILOGE("bluetooth is off.");
432 return;
433 }
434
435 if (pimpl == nullptr || !pimpl->proxy_) {
436 HILOGE("pimpl or avrcpTarget proxy is nullptr");
437 return;
438 }
439
440 pimpl->proxy_->NotifyNowPlayingContentChanged();
441 }
442
NotifyAvailablePlayersChanged(void)443 void AvrcpTarget::NotifyAvailablePlayersChanged(void)
444 {
445 HILOGI("enter");
446 if (!IS_BT_ENABLED()) {
447 HILOGE("bluetooth is off.");
448 return;
449 }
450
451 if (pimpl == nullptr || !pimpl->proxy_) {
452 HILOGE("pimpl or avrcpTarget proxy is nullptr");
453 return;
454 }
455
456 pimpl->proxy_->NotifyAvailablePlayersChanged();
457 }
458
NotifyAddressedPlayerChanged(uint16_t playerId,uint16_t uidCounter)459 void AvrcpTarget::NotifyAddressedPlayerChanged(uint16_t playerId, uint16_t uidCounter)
460 {
461 HILOGI("enter, playerId: %{public}d, uidCounter: %{public}d", playerId, uidCounter);
462 if (!IS_BT_ENABLED()) {
463 HILOGE("bluetooth is off.");
464 return;
465 }
466
467 if (pimpl == nullptr || !pimpl->proxy_) {
468 HILOGE("pimpl or avrcpTarget proxy is nullptr");
469 return;
470 }
471
472 pimpl->proxy_->NotifyAddressedPlayerChanged(static_cast<int32_t>(playerId), static_cast<int32_t>(uidCounter));
473 }
474
NotifyUidChanged(uint16_t uidCounter)475 void AvrcpTarget::NotifyUidChanged(uint16_t uidCounter)
476 {
477 HILOGI("enter, uidCounter: %{public}d", uidCounter);
478 if (!IS_BT_ENABLED()) {
479 HILOGE("bluetooth is off.");
480 return;
481 }
482
483 if (pimpl == nullptr || !pimpl->proxy_) {
484 HILOGE("pimpl or avrcpTarget proxy is nullptr");
485 return;
486 }
487
488 pimpl->proxy_->NotifyUidChanged(static_cast<int32_t>(uidCounter));
489 }
490
NotifyVolumeChanged(uint8_t volume)491 void AvrcpTarget::NotifyVolumeChanged(uint8_t volume)
492 {
493 HILOGI("enter, volume: %{public}d", volume);
494 if (!IS_BT_ENABLED()) {
495 HILOGE("bluetooth is off.");
496 return;
497 }
498
499 if (pimpl == nullptr || !pimpl->proxy_) {
500 HILOGE("pimpl or avrcpTarget proxy is nullptr");
501 return;
502 }
503
504 pimpl->proxy_->NotifyVolumeChanged(static_cast<int32_t>(volume));
505 }
506
AvrcpTarget(void)507 AvrcpTarget::AvrcpTarget(void)
508 {
509 HILOGI("enter");
510
511 pimpl = std::make_unique<impl>();
512 }
513
~AvrcpTarget(void)514 AvrcpTarget::~AvrcpTarget(void)
515 {
516 HILOGI("enter");
517 if (!pimpl || !pimpl->proxy_) {
518 return;
519 }
520 pimpl->proxy_->AsObject()->RemoveDeathRecipient(pimpl->deathRecipient_);
521 pimpl = nullptr;
522 }
523 } // namespace Bluetooth
524 } // namespace OHOS
525