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_log.h"
26 #include "bluetooth_utils.h"
27 #include "bluetooth_observer_list.h"
28 #include "iservice_registry.h"
29 #include "raw_address.h"
30 #include "system_ability_definition.h"
31 #include "bluetooth_avrcp_tg.h"
32
33 namespace OHOS {
34 namespace Bluetooth {
35 struct AvrcpTarget::impl {
36 public:
37 class ObserverImpl : public BluetoothAvrcpTgObserverStub {
38 public:
ObserverImpl(AvrcpTarget::impl * impl)39 explicit ObserverImpl(AvrcpTarget::impl *impl) : impl_(impl)
40 {}
41 ~ObserverImpl() override = default;
42
OnConnectionStateChanged(const BluetoothRawAddress & addr,int32_t state)43 void OnConnectionStateChanged(const BluetoothRawAddress &addr, int32_t state) override
44 {
45 HILOGI("enter, address: %{public}s, state: %{public}d", GetEncryptAddr(addr.GetAddress()).c_str(), state);
46 BluetoothRemoteDevice device(addr.GetAddress(), BTTransport::ADAPTER_BREDR);
47 impl_->OnConnectionStateChanged(device, static_cast<int>(state));
48
49 return;
50 }
51
52 private:
53 AvrcpTarget::impl *impl_;
54 };
55
56 class AvrcpTgDeathRecipient final : public IRemoteObject::DeathRecipient {
57 public:
AvrcpTgDeathRecipient(AvrcpTarget::impl & avrcpTgServer)58 AvrcpTgDeathRecipient(AvrcpTarget::impl &avrcpTgServer) : avrcpTgServer_(avrcpTgServer) {};
59 ~AvrcpTgDeathRecipient() final = default;
60 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(AvrcpTgDeathRecipient);
61
OnRemoteDied(const wptr<IRemoteObject> & remote)62 void OnRemoteDied(const wptr<IRemoteObject> &remote) final
63 {
64 HILOGI("starts");
65 avrcpTgServer_.proxy_->AsObject()->RemoveDeathRecipient(avrcpTgServer_.deathRecipient_);
66 avrcpTgServer_.proxy_ = nullptr;
67 }
68
69 private:
70 AvrcpTarget::impl &avrcpTgServer_;
71 };
72
implOHOS::Bluetooth::AvrcpTarget::impl73 impl()
74 {
75 HILOGI("enter");
76
77 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
78 sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
79 if (!hostRemote) {
80 HILOGI("failed: no hostRemote");
81 return;
82 }
83
84 sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
85 sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_AVRCP_TG);
86 if (!remote) {
87 HILOGI("failed: no remote");
88 return;
89 }
90 HILOGI("remote obtained");
91 proxy_ = iface_cast<IBluetoothAvrcpTg>(remote);
92
93 deathRecipient_ = new AvrcpTgDeathRecipient(*this);
94 if (!proxy_) {
95 HILOGI("proxy_ is null when used!");
96 } else {
97 proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
98 }
99
100 observer_ = new (std::nothrow) ObserverImpl(this);
101 proxy_->RegisterObserver(observer_);
102 }
103
~implOHOS::Bluetooth::AvrcpTarget::impl104 ~impl()
105 {
106 HILOGI("enter");
107 proxy_->UnregisterObserver(observer_);
108 }
109
IsEnabledOHOS::Bluetooth::AvrcpTarget::impl110 bool IsEnabled(void)
111 {
112 HILOGI("enter");
113
114 return (proxy_ != nullptr && !BluetoothHost::GetDefaultHost().IsBtDiscovering());
115 }
116
OnConnectionStateChangedOHOS::Bluetooth::AvrcpTarget::impl117 void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state)
118 {
119 HILOGI("enter, device: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state);
120 std::lock_guard<std::mutex> lock(observerMutex_);
121 observers_.ForEach([device, state](std::shared_ptr<IObserver> observer) {
122 observer->OnConnectionStateChanged(device, state);
123 });
124 }
125
126 std::mutex observerMutex_;
127 sptr<IBluetoothAvrcpTg> proxy_;
128 BluetoothObserverList<AvrcpTarget::IObserver> observers_;
129 sptr<ObserverImpl> observer_;
130 sptr<AvrcpTgDeathRecipient> deathRecipient_;
131 };
132
GetProfile(void)133 AvrcpTarget *AvrcpTarget::GetProfile(void)
134 {
135 HILOGI("enter");
136
137 static AvrcpTarget instance;
138
139 return &instance;
140 }
141
142 /******************************************************************
143 * REGISTER / UNREGISTER OBSERVER *
144 ******************************************************************/
145
RegisterObserver(AvrcpTarget::IObserver * observer)146 void AvrcpTarget::RegisterObserver(AvrcpTarget::IObserver *observer)
147 {
148 HILOGI("enter");
149
150 std::lock_guard<std::mutex> lock(pimpl->observerMutex_);
151 if (pimpl->IsEnabled()) {
152 std::shared_ptr<IObserver> observerPtr(observer, [](IObserver *) {});
153 pimpl->observers_.Register(observerPtr);
154 }
155 }
156
UnregisterObserver(AvrcpTarget::IObserver * observer)157 void AvrcpTarget::UnregisterObserver(AvrcpTarget::IObserver *observer)
158 {
159 HILOGI("enter");
160
161 std::lock_guard<std::mutex> lock(pimpl->observerMutex_);
162
163 std::shared_ptr<IObserver> observerPtr(observer, [](IObserver *) {});
164 if (pimpl->IsEnabled()) {
165 pimpl->observers_.Deregister(observerPtr);
166 }
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
177 if (pimpl->IsEnabled()) {
178 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
179 pimpl->proxy_->SetActiveDevice(rawAddr);
180 }
181 }
182
GetConnectedDevices(void)183 std::vector<BluetoothRemoteDevice> AvrcpTarget::GetConnectedDevices(void)
184 {
185 HILOGI("enter");
186
187 std::vector<BluetoothRemoteDevice> devices;
188
189 if (pimpl->IsEnabled()) {
190 std::vector<BluetoothRawAddress> rawAddrs = pimpl->proxy_->GetConnectedDevices();
191
192 for (auto rawAddr : rawAddrs) {
193 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
194 devices.push_back(device);
195 }
196 }
197
198 return devices;
199 }
200
GetDevicesByStates(std::vector<int> states)201 std::vector<BluetoothRemoteDevice> AvrcpTarget::GetDevicesByStates(std::vector<int> states)
202 {
203 HILOGI("enter");
204
205 std::vector<BluetoothRemoteDevice> devices;
206
207 if (pimpl->IsEnabled()) {
208 std::vector<int32_t> convertStates;
209 for (auto state : states) {
210 convertStates.push_back(static_cast<int32_t>(state));
211 }
212 std::vector<BluetoothRawAddress> rawAddrs = pimpl->proxy_->GetDevicesByStates(convertStates);
213
214 for (auto rawAddr : rawAddrs) {
215 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
216 devices.push_back(device);
217 }
218 }
219
220 return devices;
221 }
222
GetDeviceState(const BluetoothRemoteDevice & device)223 int AvrcpTarget::GetDeviceState(const BluetoothRemoteDevice &device)
224 {
225 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
226
227 int32_t result = static_cast<int32_t>(BTConnectState::DISCONNECTED);
228
229 if (pimpl->IsEnabled()) {
230 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
231 result = pimpl->proxy_->GetDeviceState(rawAddr);
232 }
233
234 return static_cast<int>(result);
235 }
236
Connect(const BluetoothRemoteDevice & device)237 bool AvrcpTarget::Connect(const BluetoothRemoteDevice &device)
238 {
239 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
240
241 int result = RET_BAD_STATUS;
242
243 if (pimpl->IsEnabled()) {
244 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
245 result = pimpl->proxy_->Connect(rawAddr);
246 }
247
248 return result == RET_NO_ERROR ? true : false;
249 }
250
Disconnect(const BluetoothRemoteDevice & device)251 bool AvrcpTarget::Disconnect(const BluetoothRemoteDevice &device)
252 {
253 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
254
255 int result = RET_BAD_STATUS;
256
257 if (pimpl->IsEnabled()) {
258 BluetoothRawAddress rawAddr(device.GetDeviceAddr());
259 result = pimpl->proxy_->Disconnect(rawAddr);
260 }
261
262 return result == RET_NO_ERROR ? true : false;
263 }
264
265 /******************************************************************
266 * NOTIFICATION *
267 ******************************************************************/
268
NotifyPlaybackStatusChanged(uint8_t playStatus,uint32_t playbackPos)269 void AvrcpTarget::NotifyPlaybackStatusChanged(uint8_t playStatus, uint32_t playbackPos)
270 {
271 HILOGI("enter, playStatus: %{public}d, playbackPos: %{public}d", playStatus, playbackPos);
272
273 if (pimpl->IsEnabled()) {
274 pimpl->proxy_->NotifyPlaybackStatusChanged(
275 static_cast<int32_t>(playStatus), static_cast<int32_t>(playbackPos));
276 }
277 }
278
NotifyTrackChanged(uint64_t uid,uint32_t playbackPos)279 void AvrcpTarget::NotifyTrackChanged(uint64_t uid, uint32_t playbackPos)
280 {
281 HILOGI("enter, playbackPos: %{public}d", playbackPos);
282
283 if (pimpl->IsEnabled()) {
284 pimpl->proxy_->NotifyTrackChanged(static_cast<int64_t>(uid), static_cast<int32_t>(playbackPos));
285 }
286 }
287
NotifyTrackReachedEnd(uint32_t playbackPos)288 void AvrcpTarget::NotifyTrackReachedEnd(uint32_t playbackPos)
289 {
290 HILOGI("enter, playbackPos: %{public}d", playbackPos);
291
292 if (pimpl->IsEnabled()) {
293 pimpl->proxy_->NotifyTrackReachedEnd(static_cast<int32_t>(playbackPos));
294 }
295 }
296
NotifyTrackReachedStart(uint32_t playbackPos)297 void AvrcpTarget::NotifyTrackReachedStart(uint32_t playbackPos)
298 {
299 HILOGI("enter, playbackPos: %{public}d", playbackPos);
300
301 if (pimpl->IsEnabled()) {
302 pimpl->proxy_->NotifyTrackReachedStart(static_cast<int32_t>(playbackPos));
303 }
304 }
305
NotifyPlaybackPosChanged(uint32_t playbackPos)306 void AvrcpTarget::NotifyPlaybackPosChanged(uint32_t playbackPos)
307 {
308 HILOGI("enter, playbackPos: %{public}d", playbackPos);
309
310 if (pimpl->IsEnabled()) {
311 pimpl->proxy_->NotifyPlaybackPosChanged(static_cast<int32_t>(playbackPos));
312 }
313 }
314
NotifyPlayerAppSettingChanged(const std::vector<uint8_t> & attributes,const std::vector<uint8_t> & values)315 void AvrcpTarget::NotifyPlayerAppSettingChanged(
316 const std::vector<uint8_t> &attributes, const std::vector<uint8_t> &values)
317 {
318 HILOGI("enter");
319
320 std::vector<int32_t> attrs;
321 std::vector<int32_t> vals;
322
323 for (auto attribute : attributes) {
324 attrs.push_back(attribute);
325 }
326 for (auto value : values) {
327 vals.push_back(value);
328 }
329
330 if (pimpl->IsEnabled()) {
331 pimpl->proxy_->NotifyPlayerAppSettingChanged(attrs, vals);
332 }
333 }
334
NotifyNowPlayingContentChanged(void)335 void AvrcpTarget::NotifyNowPlayingContentChanged(void)
336 {
337 HILOGI("enter");
338
339 if (pimpl->IsEnabled()) {
340 pimpl->proxy_->NotifyNowPlayingContentChanged();
341 }
342 }
343
NotifyAvailablePlayersChanged(void)344 void AvrcpTarget::NotifyAvailablePlayersChanged(void)
345 {
346 HILOGI("enter");
347
348 if (pimpl->IsEnabled()) {
349 pimpl->proxy_->NotifyAvailablePlayersChanged();
350 }
351 }
352
NotifyAddressedPlayerChanged(uint16_t playerId,uint16_t uidCounter)353 void AvrcpTarget::NotifyAddressedPlayerChanged(uint16_t playerId, uint16_t uidCounter)
354 {
355 HILOGI("enter, playerId: %{public}d, uidCounter: %{public}d", playerId, uidCounter);
356
357 if (pimpl->IsEnabled()) {
358 pimpl->proxy_->NotifyAddressedPlayerChanged(
359 static_cast<int32_t>(playerId), static_cast<int32_t>(uidCounter));
360 }
361 }
362
NotifyUidChanged(uint16_t uidCounter)363 void AvrcpTarget::NotifyUidChanged(uint16_t uidCounter)
364 {
365 HILOGI("enter, uidCounter: %{public}d", uidCounter);
366
367 if (pimpl->IsEnabled()) {
368 pimpl->proxy_->NotifyUidChanged(static_cast<int32_t>(uidCounter));
369 }
370 }
371
NotifyVolumeChanged(uint8_t volume)372 void AvrcpTarget::NotifyVolumeChanged(uint8_t volume)
373 {
374 HILOGI("enter, volume: %{public}d", volume);
375
376 if (pimpl->IsEnabled()) {
377 pimpl->proxy_->NotifyVolumeChanged(static_cast<int32_t>(volume));
378 }
379 }
380
AvrcpTarget(void)381 AvrcpTarget::AvrcpTarget(void)
382 {
383 HILOGI("enter");
384
385 pimpl = std::make_unique<impl>();
386 }
387
~AvrcpTarget(void)388 AvrcpTarget::~AvrcpTarget(void)
389 {
390 HILOGI("enter");
391
392 pimpl->proxy_->AsObject()->RemoveDeathRecipient(pimpl->deathRecipient_);
393 pimpl = nullptr;
394 }
395 } // namespace Bluetooth
396 } // namespace OHOS
397