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