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