• 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 #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     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
157     CHECK_AND_RETURN_LOG(observer != nullptr, "observer 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     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
165     pimpl->observers_.Deregister(observer);
166 }
167 
168 /******************************************************************
169  * CONNECTION                                                     *
170  ******************************************************************/
171 
SetActiveDevice(const BluetoothRemoteDevice & device)172 void AvrcpTarget::SetActiveDevice(const BluetoothRemoteDevice &device)
173 {
174     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
175     if (!IS_BT_ENABLED()) {
176         HILOGE("bluetooth is off.");
177         return;
178     }
179     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
180     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
181 
182     BluetoothRawAddress rawAddr(device.GetDeviceAddr());
183     proxy->SetActiveDevice(rawAddr);
184 }
185 
GetConnectedDevices(void)186 std::vector<BluetoothRemoteDevice> AvrcpTarget::GetConnectedDevices(void)
187 {
188     if (!IS_BT_ENABLED()) {
189         HILOGE("bluetooth is off.");
190         return std::vector<BluetoothRemoteDevice>();
191     }
192 
193     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
194     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(), "proxy is nullptr");
195 
196     std::vector<BluetoothRemoteDevice> devices;
197     std::vector<BluetoothRawAddress> rawAddrs = proxy->GetConnectedDevices();
198     for (auto rawAddr : rawAddrs) {
199         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
200         devices.push_back(device);
201     }
202     return devices;
203 }
204 
GetDevicesByStates(std::vector<int> states)205 std::vector<BluetoothRemoteDevice> AvrcpTarget::GetDevicesByStates(std::vector<int> states)
206 {
207     if (!IS_BT_ENABLED()) {
208         HILOGE("bluetooth is off.");
209         return std::vector<BluetoothRemoteDevice>();
210     }
211     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
212     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(), "proxy is nullptr");
213 
214     std::vector<int32_t> convertStates;
215     for (auto state : states) {
216         convertStates.push_back(static_cast<int32_t>(state));
217     }
218 
219     std::vector<BluetoothRemoteDevice> devices;
220     std::vector<BluetoothRawAddress> rawAddrs = proxy->GetDevicesByStates(convertStates);
221     for (auto rawAddr : rawAddrs) {
222         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
223         devices.push_back(device);
224     }
225 
226     return devices;
227 }
228 
GetDeviceState(const BluetoothRemoteDevice & device)229 int AvrcpTarget::GetDeviceState(const BluetoothRemoteDevice &device)
230 {
231     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
232 
233     if (!IS_BT_ENABLED()) {
234         HILOGE("bluetooth is off.");
235         return static_cast<int32_t>(BTConnectState::DISCONNECTED);
236     }
237     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
238     CHECK_AND_RETURN_LOG_RET(proxy != nullptr,
239         static_cast<int32_t>(BTConnectState::DISCONNECTED), "proxy is nullptr");
240 
241     BluetoothRawAddress rawAddr(device.GetDeviceAddr());
242     int32_t result = proxy->GetDeviceState(rawAddr);
243     return static_cast<int>(result);
244 }
245 
Connect(const BluetoothRemoteDevice & device)246 bool AvrcpTarget::Connect(const BluetoothRemoteDevice &device)
247 {
248     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
249 
250     if (!IS_BT_ENABLED()) {
251         HILOGE("bluetooth is off.");
252         return RET_BAD_STATUS;
253     }
254     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
255     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "proxy is nullptr");
256 
257     BluetoothRawAddress rawAddr(device.GetDeviceAddr());
258     int result = proxy->Connect(rawAddr);
259     return result == RET_NO_ERROR;
260 }
261 
Disconnect(const BluetoothRemoteDevice & device)262 bool AvrcpTarget::Disconnect(const BluetoothRemoteDevice &device)
263 {
264     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
265 
266     if (!IS_BT_ENABLED()) {
267         HILOGE("bluetooth is off.");
268         return RET_BAD_STATUS;
269     }
270 
271     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
272     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "proxy is nullptr");
273 
274     BluetoothRawAddress rawAddr(device.GetDeviceAddr());
275     int result = proxy->Disconnect(rawAddr);
276     return result == RET_NO_ERROR;
277 }
278 
279 /******************************************************************
280  * NOTIFICATION                                                   *
281  ******************************************************************/
282 
NotifyPlaybackStatusChanged(uint8_t playStatus,uint32_t playbackPos)283 void AvrcpTarget::NotifyPlaybackStatusChanged(uint8_t playStatus, uint32_t playbackPos)
284 {
285     HILOGI("enter, playStatus: %{public}d, playbackPos: %{public}d", playStatus, playbackPos);
286     if (!IS_BT_ENABLED()) {
287         HILOGE("bluetooth is off.");
288         return;
289     }
290     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
291     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
292 
293     proxy->NotifyPlaybackStatusChanged(static_cast<int32_t>(playStatus), static_cast<int32_t>(playbackPos));
294 }
295 
NotifyTrackChanged(uint64_t uid,uint32_t playbackPos)296 void AvrcpTarget::NotifyTrackChanged(uint64_t uid, uint32_t playbackPos)
297 {
298     HILOGI("enter, playbackPos: %{public}d", playbackPos);
299     if (!IS_BT_ENABLED()) {
300         HILOGE("bluetooth is off.");
301         return;
302     }
303 
304     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
305     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
306 
307     proxy->NotifyTrackChanged(static_cast<int64_t>(uid), static_cast<int32_t>(playbackPos));
308 }
309 
NotifyTrackReachedEnd(uint32_t playbackPos)310 void AvrcpTarget::NotifyTrackReachedEnd(uint32_t playbackPos)
311 {
312     HILOGI("enter, playbackPos: %{public}d", playbackPos);
313     if (!IS_BT_ENABLED()) {
314         HILOGE("bluetooth is off.");
315         return;
316     }
317     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
318     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
319 
320     proxy->NotifyTrackReachedEnd(static_cast<int32_t>(playbackPos));
321 }
322 
NotifyTrackReachedStart(uint32_t playbackPos)323 void AvrcpTarget::NotifyTrackReachedStart(uint32_t playbackPos)
324 {
325     HILOGI("enter, playbackPos: %{public}d", playbackPos);
326     if (!IS_BT_ENABLED()) {
327         HILOGE("bluetooth is off.");
328         return;
329     }
330 
331     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
332     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
333 
334     proxy->NotifyTrackReachedStart(static_cast<int32_t>(playbackPos));
335 }
336 
NotifyPlaybackPosChanged(uint32_t playbackPos)337 void AvrcpTarget::NotifyPlaybackPosChanged(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     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
346     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
347 
348     proxy->NotifyPlaybackPosChanged(static_cast<int32_t>(playbackPos));
349 }
350 
NotifyPlayerAppSettingChanged(const std::vector<uint8_t> & attributes,const std::vector<uint8_t> & values)351 void AvrcpTarget::NotifyPlayerAppSettingChanged(const std::vector<uint8_t> &attributes,
352     const std::vector<uint8_t> &values)
353 {
354     HILOGI("enter");
355     if (!IS_BT_ENABLED()) {
356         HILOGE("bluetooth is off.");
357         return;
358     }
359 
360     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
361     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
362 
363     std::vector<int32_t> attrs;
364     for (auto attribute : attributes) {
365         attrs.push_back(attribute);
366     }
367     std::vector<int32_t> vals;
368     for (auto value : values) {
369         vals.push_back(value);
370     }
371 
372     proxy->NotifyPlayerAppSettingChanged(attrs, vals);
373 }
374 
NotifyNowPlayingContentChanged(void)375 void AvrcpTarget::NotifyNowPlayingContentChanged(void)
376 {
377     HILOGI("enter");
378     if (!IS_BT_ENABLED()) {
379         HILOGE("bluetooth is off.");
380         return;
381     }
382 
383     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
384     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
385 
386     proxy->NotifyNowPlayingContentChanged();
387 }
388 
NotifyAvailablePlayersChanged(void)389 void AvrcpTarget::NotifyAvailablePlayersChanged(void)
390 {
391     HILOGI("enter");
392     if (!IS_BT_ENABLED()) {
393         HILOGE("bluetooth is off.");
394         return;
395     }
396 
397     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
398     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
399 
400     proxy->NotifyAvailablePlayersChanged();
401 }
402 
NotifyAddressedPlayerChanged(uint16_t playerId,uint16_t uidCounter)403 void AvrcpTarget::NotifyAddressedPlayerChanged(uint16_t playerId, uint16_t uidCounter)
404 {
405     HILOGI("enter, playerId: %{public}d, uidCounter: %{public}d", playerId, uidCounter);
406     if (!IS_BT_ENABLED()) {
407         HILOGE("bluetooth is off.");
408         return;
409     }
410 
411     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
412     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
413 
414     proxy->NotifyAddressedPlayerChanged(static_cast<int32_t>(playerId), static_cast<int32_t>(uidCounter));
415 }
416 
NotifyUidChanged(uint16_t uidCounter)417 void AvrcpTarget::NotifyUidChanged(uint16_t uidCounter)
418 {
419     HILOGI("enter, uidCounter: %{public}d", uidCounter);
420     if (!IS_BT_ENABLED()) {
421         HILOGE("bluetooth is off.");
422         return;
423     }
424 
425     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
426     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
427 
428     proxy->NotifyUidChanged(static_cast<int32_t>(uidCounter));
429 }
430 
NotifyVolumeChanged(uint8_t volume)431 void AvrcpTarget::NotifyVolumeChanged(uint8_t volume)
432 {
433     HILOGI("enter, volume: %{public}d", volume);
434     if (!IS_BT_ENABLED()) {
435         HILOGE("bluetooth is off.");
436         return;
437     }
438 
439     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
440     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
441 
442     proxy->NotifyVolumeChanged(static_cast<int32_t>(volume));
443 }
444 
AvrcpTarget(void)445 AvrcpTarget::AvrcpTarget(void)
446 {
447     HILOGI("enter");
448 
449     pimpl = std::make_unique<impl>();
450 }
451 
~AvrcpTarget(void)452 AvrcpTarget::~AvrcpTarget(void)
453 {
454     HILOGI("enter");
455     sptr<IBluetoothAvrcpTg> proxy = GetRemoteProxy<IBluetoothAvrcpTg>(PROFILE_AVRCP_TG);
456     CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
457     pimpl = nullptr;
458 }
459 } // namespace Bluetooth
460 } // namespace OHOS
461