• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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