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