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