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