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 #include "bluetooth_a2dp_snk.h"
16 #include <cstdint>
17 #include "bluetooth_a2dp_sink_observer_stub.h"
18 #include "bluetooth_def.h"
19 #include "bluetooth_host.h"
20 #include "bluetooth_load_system_ability.h"
21 #include "bluetooth_log.h"
22 #include "bluetooth_observer_list.h"
23 #include "bluetooth_remote_device.h"
24 #include "bluetooth_types.h"
25 #include "bluetooth_utils.h"
26 #include "functional"
27 #include "i_bluetooth_a2dp_sink.h"
28 #include "i_bluetooth_a2dp_sink_observer.h"
29 #include "i_bluetooth_host.h"
30 #include "if_system_ability_manager.h"
31 #include "iosfwd"
32 #include "iremote_broker.h"
33 #include "iremote_object.h"
34 #include "iservice_registry.h"
35 #include "list"
36 #include "memory"
37 #include "new"
38 #include "raw_address.h"
39 #include "refbase.h"
40 #include "string"
41 #include "system_ability_definition.h"
42 #include "vector"
43
44 namespace OHOS {
45 namespace Bluetooth {
46 using namespace OHOS::bluetooth;
47 std::mutex g_a2dpSnkProxyMutex;
48 struct A2dpSink::impl {
49 impl();
50 ~impl();
51 bool InitA2dpSinkProxy(void);
52
53 BluetoothObserverList<A2dpSinkObserver> observers_;
54 sptr<IBluetoothA2dpSink> proxy_ = nullptr;
55 class BluetoothA2dpSinkObserverImp;
56 sptr<BluetoothA2dpSinkObserverImp> observerImp_ = nullptr;
57 class BluetoothA2dpSinkDeathRecipient;
58 sptr<BluetoothA2dpSinkDeathRecipient> deathRecipient_ = nullptr;
59 };
60
61 class A2dpSink::impl::BluetoothA2dpSinkObserverImp : public BluetoothA2dpSinkObserverStub {
62 public:
BluetoothA2dpSinkObserverImp(A2dpSink::impl & a2dpSink)63 explicit BluetoothA2dpSinkObserverImp(A2dpSink::impl &a2dpSink) : a2dpSink_(a2dpSink)
64 {};
~BluetoothA2dpSinkObserverImp()65 ~BluetoothA2dpSinkObserverImp() override
66 {};
67
Register(std::shared_ptr<A2dpSinkObserver> & observer)68 void Register(std::shared_ptr<A2dpSinkObserver> &observer)
69 {
70 HILOGI("enter");
71 a2dpSink_.observers_.Register(observer);
72 }
73
Deregister(std::shared_ptr<A2dpSinkObserver> & observer)74 void Deregister(std::shared_ptr<A2dpSinkObserver> &observer)
75 {
76 HILOGI("enter");
77 a2dpSink_.observers_.Deregister(observer);
78 }
79
OnConnectionStateChanged(const RawAddress & device,int state)80 void OnConnectionStateChanged(const RawAddress &device, int state) override
81 {
82 HILOGD("device: %{public}s, state: %{public}d", GetEncryptAddr(device.GetAddress()).c_str(), state);
83 a2dpSink_.observers_.ForEach([device, state](std::shared_ptr<A2dpSinkObserver> observer) {
84 observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state);
85 });
86 }
87
88 private:
89 A2dpSink::impl &a2dpSink_;
90 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkObserverImp);
91 };
92
93 class A2dpSink::impl::BluetoothA2dpSinkDeathRecipient final : public IRemoteObject::DeathRecipient {
94 public:
BluetoothA2dpSinkDeathRecipient(A2dpSink::impl & a2dpSinkDeath)95 explicit BluetoothA2dpSinkDeathRecipient(A2dpSink::impl &a2dpSinkDeath) : a2dpSinkDeath_(a2dpSinkDeath)
96 {};
97 ~BluetoothA2dpSinkDeathRecipient() final = default;
98 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkDeathRecipient);
99
OnRemoteDied(const wptr<IRemoteObject> & remote)100 void OnRemoteDied(const wptr<IRemoteObject> &remote) final
101 {
102 HILOGI("enter");
103 std::lock_guard<std::mutex> lock(g_a2dpSnkProxyMutex);
104 if (!a2dpSinkDeath_.proxy_) {
105 return;
106 }
107 a2dpSinkDeath_.proxy_ = nullptr;
108 }
109
110 private:
111 A2dpSink::impl &a2dpSinkDeath_;
112 };
113
impl()114 A2dpSink::impl::impl()
115 {
116 HILOGI("start");
117 if (proxy_) {
118 return;
119 }
120 BluetootLoadSystemAbility::GetInstance().RegisterNotifyMsg(PROFILE_ID_A2DP_SINK);
121 if (!BluetootLoadSystemAbility::GetInstance().HasSubscribedBluetoothSystemAbility()) {
122 BluetootLoadSystemAbility::GetInstance().SubScribeBluetoothSystemAbility();
123 return;
124 }
125 InitA2dpSinkProxy();
126 };
127
~impl()128 A2dpSink::impl::~impl()
129 {
130 HILOGI("start");
131 if (proxy_ != nullptr) {
132 proxy_->DeregisterObserver(observerImp_);
133 proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
134 }
135 }
136
InitA2dpSinkProxy(void)137 bool A2dpSink::impl::InitA2dpSinkProxy(void)
138 {
139 std::lock_guard<std::mutex> lock(g_a2dpSnkProxyMutex);
140 if (proxy_) {
141 return true;
142 }
143 HILOGI("Enter!");
144 proxy_ = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
145 if (!proxy_) {
146 HILOGE("get A2dpSink proxy_ failed");
147 return false;
148 }
149
150 deathRecipient_ = new BluetoothA2dpSinkDeathRecipient(*this);
151 if (deathRecipient_ != nullptr) {
152 proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
153 }
154
155 observerImp_ = new (std::nothrow) BluetoothA2dpSinkObserverImp(*this);
156 if (observerImp_ != nullptr) {
157 proxy_->RegisterObserver(observerImp_);
158 }
159 return true;
160 }
161
A2dpSink()162 A2dpSink::A2dpSink()
163 {
164 pimpl = std::make_unique<impl>();
165 if (!pimpl) {
166 HILOGE("fails: no pimpl");
167 }
168 }
169
Init()170 void A2dpSink::Init()
171 {
172 if (!pimpl) {
173 HILOGE("fails: no pimpl");
174 return;
175 }
176 if (!pimpl->InitA2dpSinkProxy()) {
177 HILOGE("A2dpSink proxy is nullptr");
178 return;
179 }
180 }
181
~A2dpSink()182 A2dpSink::~A2dpSink()
183 {
184 HILOGI("start");
185 }
186
RegisterObserver(A2dpSinkObserver * observer)187 void A2dpSink::RegisterObserver(A2dpSinkObserver *observer)
188 {
189 HILOGI("enter");
190 std::shared_ptr<A2dpSinkObserver> pointer(observer, [](A2dpSinkObserver *) {});
191 pimpl->observers_.Register(pointer);
192 }
193
DeregisterObserver(A2dpSinkObserver * observer)194 void A2dpSink::DeregisterObserver(A2dpSinkObserver *observer)
195 {
196 HILOGI("enter");
197 std::shared_ptr<A2dpSinkObserver> pointer(observer, [](A2dpSinkObserver *) {});
198 pimpl->observers_.Deregister(pointer);
199 }
200
GetDeviceState(const BluetoothRemoteDevice & device) const201 int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const
202 {
203 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
204 if (!IS_BT_ENABLED()) {
205 HILOGE("bluetooth is off.");
206 return RET_BAD_STATUS;
207 }
208
209 if (pimpl == nullptr || !pimpl->proxy_) {
210 HILOGE("pimpl or A2dpSink proxy is nullptr");
211 return RET_BAD_STATUS;
212 }
213
214 if (!device.IsValidBluetoothRemoteDevice()) {
215 HILOGE("input parameter error.");
216 return RET_BAD_PARAM;
217 }
218
219 return pimpl->proxy_->GetDeviceState(RawAddress(device.GetDeviceAddr()));
220 }
221
GetDevicesByStates(std::vector<int> states) const222 std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const
223 {
224 HILOGI("enter");
225
226 if (!IS_BT_ENABLED()) {
227 HILOGE("bluetooth is off.");
228 return std::vector<BluetoothRemoteDevice>();
229 }
230
231 if (pimpl == nullptr || !pimpl->proxy_) {
232 HILOGE("pimpl or A2dpSink proxy is nullptr");
233 return std::vector<BluetoothRemoteDevice>();
234 }
235
236 std::vector<int32_t> convertStates;
237 for (auto state : states) {
238 convertStates.push_back(static_cast<int32_t>(state));
239 }
240 std::vector<BluetoothRemoteDevice> devices;
241 std::vector<RawAddress> rawAddrs = pimpl->proxy_->GetDevicesByStates(convertStates);
242 for (auto rawAddr : rawAddrs) {
243 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
244 devices.push_back(device);
245 }
246 return devices;
247 }
248
GetPlayingState(const BluetoothRemoteDevice & device) const249 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const
250 {
251 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
252 if (!IS_BT_ENABLED()) {
253 HILOGE("bluetooth is off.");
254 return RET_BAD_STATUS;
255 }
256
257 if (pimpl == nullptr || !pimpl->proxy_) {
258 HILOGE("pimpl or A2dpSink proxy is nullptr");
259 return RET_BAD_STATUS;
260 }
261
262 if (!device.IsValidBluetoothRemoteDevice()) {
263 HILOGE("input parameter error.");
264 return RET_BAD_PARAM;
265 }
266
267 int ret = RET_BAD_STATUS;
268 pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
269 return ret;
270 }
271
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const272 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
273 {
274 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
275 if (!IS_BT_ENABLED()) {
276 HILOGE("bluetooth is off.");
277 return RET_BAD_STATUS;
278 }
279
280 if (pimpl == nullptr || !pimpl->proxy_) {
281 HILOGE("pimpl or A2dpSink proxy is nullptr");
282 return RET_BAD_STATUS;
283 }
284
285 if (!device.IsValidBluetoothRemoteDevice()) {
286 HILOGE("input parameter error.");
287 return RET_BAD_PARAM;
288 }
289
290 return pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
291 }
292
Connect(const BluetoothRemoteDevice & device)293 bool A2dpSink::Connect(const BluetoothRemoteDevice &device)
294 {
295 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
296 if (!IS_BT_ENABLED()) {
297 HILOGE("bluetooth is off.");
298 return false;
299 }
300
301 if (pimpl == nullptr || !pimpl->proxy_) {
302 HILOGE("pimpl or A2dpSink proxy is nullptr");
303 return false;
304 }
305
306 if (!device.IsValidBluetoothRemoteDevice()) {
307 HILOGE("input parameter error.");
308 return false;
309 }
310
311 int ret = pimpl->proxy_->Connect(RawAddress(device.GetDeviceAddr()));
312 return (ret == RET_NO_ERROR);
313 }
314
Disconnect(const BluetoothRemoteDevice & device)315 bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device)
316 {
317 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
318 if (!IS_BT_ENABLED()) {
319 HILOGE("bluetooth is off.");
320 return false;
321 }
322
323 if (pimpl == nullptr || !pimpl->proxy_) {
324 HILOGE("pimpl or A2dpSink proxy is nullptr");
325 return false;
326 }
327
328 if (!device.IsValidBluetoothRemoteDevice()) {
329 HILOGE("input parameter error.");
330 return false;
331 }
332
333 int ret = pimpl->proxy_->Disconnect(RawAddress(device.GetDeviceAddr()));
334 return (ret == RET_NO_ERROR);
335 }
336
GetProfile()337 A2dpSink *A2dpSink::GetProfile()
338 {
339 HILOGI("enter");
340 static A2dpSink service;
341 return &service;
342 }
343
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)344 bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
345 {
346 HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
347 if (!IS_BT_ENABLED()) {
348 HILOGE("bluetooth is off.");
349 return false;
350 }
351
352 if (pimpl == nullptr || !pimpl->proxy_) {
353 HILOGE("pimpl or A2dpSink proxy is nullptr");
354 return false;
355 }
356
357 if ((!device.IsValidBluetoothRemoteDevice()) ||
358 ((strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
359 (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
360 HILOGE("input parameter error.");
361 return false;
362 }
363
364 int ret = pimpl->proxy_->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
365 return (ret == RET_NO_ERROR);
366 }
367
GetConnectStrategy(const BluetoothRemoteDevice & device) const368 int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const
369 {
370 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
371 if (!IS_BT_ENABLED()) {
372 HILOGE("bluetooth is off.");
373 return RET_BAD_STATUS;
374 }
375
376 if (pimpl == nullptr || !pimpl->proxy_) {
377 HILOGE("pimpl or A2dpSink proxy is nullptr");
378 return RET_BAD_STATUS;
379 }
380
381 if (!device.IsValidBluetoothRemoteDevice()) {
382 HILOGE("input parameter error.");
383 return RET_BAD_PARAM;
384 }
385
386 int ret = pimpl->proxy_->GetConnectStrategy(RawAddress(device.GetDeviceAddr()));
387 return ret;
388 }
389
SendDelay(const BluetoothRemoteDevice & device,uint16_t delayValue)390 bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)
391 {
392 HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue);
393 if (!IS_BT_ENABLED()) {
394 HILOGE("bluetooth is off.");
395 return false;
396 }
397
398 if (pimpl == nullptr || !pimpl->proxy_) {
399 HILOGE("pimpl or A2dpSink proxy is nullptr");
400 return false;
401 }
402
403 if (!device.IsValidBluetoothRemoteDevice()) {
404 HILOGE("input parameter error.");
405 return false;
406 }
407
408 int ret = pimpl->proxy_->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue);
409 return (ret == RET_NO_ERROR);
410 }
411 } // namespace Bluetooth
412 } // namespace OHOS