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