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