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_a2dp_snk"
17 #endif
18
19 #include "bluetooth_a2dp_snk.h"
20 #include <cstdint>
21 #include "bluetooth_a2dp_sink_observer_stub.h"
22 #include "bluetooth_def.h"
23 #include "bluetooth_host.h"
24 #include "bluetooth_profile_manager.h"
25 #include "bluetooth_log.h"
26 #include "bluetooth_observer_list.h"
27 #include "bluetooth_remote_device.h"
28 #include "bluetooth_types.h"
29 #include "bluetooth_utils.h"
30 #include "functional"
31 #include "i_bluetooth_a2dp_sink.h"
32 #include "i_bluetooth_a2dp_sink_observer.h"
33 #include "i_bluetooth_host.h"
34 #include "if_system_ability_manager.h"
35 #include "iosfwd"
36 #include "iremote_broker.h"
37 #include "iremote_object.h"
38 #include "iservice_registry.h"
39 #include "list"
40 #include "memory"
41 #include "new"
42 #include "raw_address.h"
43 #include "refbase.h"
44 #include "string"
45 #include "system_ability_definition.h"
46 #include "vector"
47
48 namespace OHOS {
49 namespace Bluetooth {
50 using namespace OHOS::bluetooth;
51 std::mutex g_a2dpSnkProxyMutex;
52 struct A2dpSink::impl {
53 impl();
54 ~impl();
55 BluetoothObserverList<A2dpSinkObserver> observers_;
56 class BluetoothA2dpSinkObserverImp;
57 sptr<BluetoothA2dpSinkObserverImp> observerImp_ = nullptr;
58 int32_t profileRegisterId = 0;
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,int cause)80 void OnConnectionStateChanged(const RawAddress &device, int state, int cause) override
81 {
82 HILOGD("device: %{public}s, state: %{public}d, cause: %{public}d",
83 GET_ENCRYPT_RAW_ADDR(device), state, cause);
84 a2dpSink_.observers_.ForEach([device, state, cause](std::shared_ptr<A2dpSinkObserver> observer) {
85 observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state, cause);
86 });
87 }
88
89 private:
90 A2dpSink::impl &a2dpSink_;
91 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkObserverImp);
92 };
93
impl()94 A2dpSink::impl::impl()
95 {
96 observerImp_ = new (std::nothrow) BluetoothA2dpSinkObserverImp(*this);
97 CHECK_AND_RETURN_LOG(observerImp_ != nullptr, "observerImp_ is nullptr");
98 profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_A2DP_SINK,
99 [this](sptr<IRemoteObject> remote) {
100 sptr<IBluetoothA2dpSink> proxy = iface_cast<IBluetoothA2dpSink>(remote);
101 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
102 proxy->RegisterObserver(observerImp_);
103 });
104 };
105
~impl()106 A2dpSink::impl::~impl()
107 {
108 HILOGD("start");
109 BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
110 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
111 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
112 proxy->DeregisterObserver(observerImp_);
113 }
114
A2dpSink()115 A2dpSink::A2dpSink()
116 {
117 pimpl = std::make_unique<impl>();
118 if (!pimpl) {
119 HILOGE("fails: no pimpl");
120 }
121 }
122
~A2dpSink()123 A2dpSink::~A2dpSink()
124 {
125 HILOGD("start");
126 }
127
RegisterObserver(std::shared_ptr<A2dpSinkObserver> observer)128 void A2dpSink::RegisterObserver(std::shared_ptr<A2dpSinkObserver> observer)
129 {
130 HILOGD("enter");
131 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
132 pimpl->observers_.Register(observer);
133 }
134
DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer)135 void A2dpSink::DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer)
136 {
137 HILOGD("enter");
138 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
139 pimpl->observers_.Deregister(observer);
140 }
141
GetDeviceState(const BluetoothRemoteDevice & device) const142 int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const
143 {
144 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
145 if (!IS_BT_ENABLED()) {
146 HILOGE("bluetooth is off.");
147 return RET_BAD_STATUS;
148 }
149 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
150 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
151 if (!device.IsValidBluetoothRemoteDevice()) {
152 HILOGE("input parameter error.");
153 return RET_BAD_PARAM;
154 }
155
156 return proxy->GetDeviceState(RawAddress(device.GetDeviceAddr()));
157 }
158
GetDevicesByStates(std::vector<int> states) const159 std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const
160 {
161 HILOGI("enter");
162
163 if (!IS_BT_ENABLED()) {
164 HILOGE("bluetooth is off.");
165 return std::vector<BluetoothRemoteDevice>();
166 }
167
168 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
169 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(),
170 "A2dpSink proxy is nullptr");
171
172 std::vector<int32_t> convertStates;
173 for (auto state : states) {
174 convertStates.push_back(static_cast<int32_t>(state));
175 }
176 std::vector<BluetoothRemoteDevice> devices;
177 std::vector<RawAddress> rawAddrs = proxy->GetDevicesByStates(convertStates);
178 for (auto rawAddr : rawAddrs) {
179 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
180 devices.push_back(device);
181 }
182 return devices;
183 }
184
GetPlayingState(const BluetoothRemoteDevice & device) const185 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const
186 {
187 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
188 if (!IS_BT_ENABLED()) {
189 HILOGE("bluetooth is off.");
190 return RET_BAD_STATUS;
191 }
192
193 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
194 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
195
196 if (!device.IsValidBluetoothRemoteDevice()) {
197 HILOGE("input parameter error.");
198 return RET_BAD_PARAM;
199 }
200
201 int ret = RET_BAD_STATUS;
202 proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
203 return ret;
204 }
205
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const206 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
207 {
208 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
209 if (!IS_BT_ENABLED()) {
210 HILOGE("bluetooth is off.");
211 return RET_BAD_STATUS;
212 }
213
214 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
215 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
216
217 if (!device.IsValidBluetoothRemoteDevice()) {
218 HILOGE("input parameter error.");
219 return RET_BAD_PARAM;
220 }
221
222 return proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
223 }
224
Connect(const BluetoothRemoteDevice & device)225 bool A2dpSink::Connect(const BluetoothRemoteDevice &device)
226 {
227 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
228 if (!IS_BT_ENABLED()) {
229 HILOGE("bluetooth is off.");
230 return false;
231 }
232
233 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
234 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
235
236 if (!device.IsValidBluetoothRemoteDevice()) {
237 HILOGE("input parameter error.");
238 return false;
239 }
240
241 int ret = proxy->Connect(RawAddress(device.GetDeviceAddr()));
242 return (ret == RET_NO_ERROR);
243 }
244
Disconnect(const BluetoothRemoteDevice & device)245 bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device)
246 {
247 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
248 if (!IS_BT_ENABLED()) {
249 HILOGE("bluetooth is off.");
250 return false;
251 }
252
253 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
254 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
255
256 if (!device.IsValidBluetoothRemoteDevice()) {
257 HILOGE("input parameter error.");
258 return false;
259 }
260
261 int ret = proxy->Disconnect(RawAddress(device.GetDeviceAddr()));
262 return (ret == RET_NO_ERROR);
263 }
264
GetProfile()265 A2dpSink *A2dpSink::GetProfile()
266 {
267 HILOGI("enter");
268 #ifdef DTFUZZ_TEST
269 static BluetoothNoDestructor<A2dpSink> service;
270 return service.get();
271 #else
272 static A2dpSink service;
273 return &service;
274 #endif
275 }
276
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)277 bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
278 {
279 HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
280 if (!IS_BT_ENABLED()) {
281 HILOGE("bluetooth is off.");
282 return false;
283 }
284 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
285 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
286
287 if ((!device.IsValidBluetoothRemoteDevice()) ||
288 ((strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
289 (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
290 HILOGE("input parameter error.");
291 return false;
292 }
293
294 int ret = proxy->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
295 return (ret == RET_NO_ERROR);
296 }
297
GetConnectStrategy(const BluetoothRemoteDevice & device) const298 int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const
299 {
300 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
301 if (!IS_BT_ENABLED()) {
302 HILOGE("bluetooth is off.");
303 return RET_BAD_STATUS;
304 }
305 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
306 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
307
308 if (!device.IsValidBluetoothRemoteDevice()) {
309 HILOGE("input parameter error.");
310 return RET_BAD_PARAM;
311 }
312
313 int ret = proxy->GetConnectStrategy(RawAddress(device.GetDeviceAddr()));
314 return ret;
315 }
316
SendDelay(const BluetoothRemoteDevice & device,uint16_t delayValue)317 bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)
318 {
319 HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue);
320 if (!IS_BT_ENABLED()) {
321 HILOGE("bluetooth is off.");
322 return false;
323 }
324 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
325 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
326
327 if (!device.IsValidBluetoothRemoteDevice()) {
328 HILOGE("input parameter error.");
329 return false;
330 }
331
332 int ret = proxy->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue);
333 return (ret == RET_NO_ERROR);
334 }
335 } // namespace Bluetooth
336 } // namespace OHOS