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