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_profile_manager.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 BluetoothObserverList<A2dpSinkObserver> observers_;
52 class BluetoothA2dpSinkObserverImp;
53 sptr<BluetoothA2dpSinkObserverImp> observerImp_ = nullptr;
54 int32_t profileRegisterId = 0;
55 };
56
57 class A2dpSink::impl::BluetoothA2dpSinkObserverImp : public BluetoothA2dpSinkObserverStub {
58 public:
BluetoothA2dpSinkObserverImp(A2dpSink::impl &a2dpSink)59 explicit BluetoothA2dpSinkObserverImp(A2dpSink::impl &a2dpSink) : a2dpSink_(a2dpSink)
60 {};
61 ~BluetoothA2dpSinkObserverImp() override
62 {};
63
Register(std::shared_ptr<A2dpSinkObserver> &observer)64 void Register(std::shared_ptr<A2dpSinkObserver> &observer)
65 {
66 HILOGI("enter");
67 a2dpSink_.observers_.Register(observer);
68 }
69
Deregister(std::shared_ptr<A2dpSinkObserver> &observer)70 void Deregister(std::shared_ptr<A2dpSinkObserver> &observer)
71 {
72 HILOGI("enter");
73 a2dpSink_.observers_.Deregister(observer);
74 }
75
76 void OnConnectionStateChanged(const RawAddress &device, int state, int cause) override
77 {
78 HILOGD("device: %{public}s, state: %{public}d, cause: %{public}d",
79 GET_ENCRYPT_RAW_ADDR(device), state, cause);
80 a2dpSink_.observers_.ForEach([device, state, cause](std::shared_ptr<A2dpSinkObserver> observer) {
81 observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state, cause);
82 });
83 }
84
85 private:
86 A2dpSink::impl &a2dpSink_;
87 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkObserverImp);
88 };
89
impl()90 A2dpSink::impl::impl()
91 {
92 observerImp_ = new (std::nothrow) BluetoothA2dpSinkObserverImp(*this);
93 CHECK_AND_RETURN_LOG(observerImp_ != nullptr, "observerImp_ is nullptr");
94 profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_A2DP_SINK,
95 [this](sptr<IRemoteObject> remote) {
96 sptr<IBluetoothA2dpSink> proxy = iface_cast<IBluetoothA2dpSink>(remote);
97 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
98 proxy->RegisterObserver(observerImp_);
99 });
100 };
101
~impl()102 A2dpSink::impl::~impl()
103 {
104 HILOGD("start");
105 BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
106 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
107 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
108 proxy->DeregisterObserver(observerImp_);
109 }
110
A2dpSink()111 A2dpSink::A2dpSink()
112 {
113 pimpl = std::make_unique<impl>();
114 if (!pimpl) {
115 HILOGE("fails: no pimpl");
116 }
117 }
118
~A2dpSink()119 A2dpSink::~A2dpSink()
120 {
121 HILOGD("start");
122 }
123
RegisterObserver(std::shared_ptr<A2dpSinkObserver> observer)124 void A2dpSink::RegisterObserver(std::shared_ptr<A2dpSinkObserver> observer)
125 {
126 HILOGD("enter");
127 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
128 pimpl->observers_.Register(observer);
129 }
130
DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer)131 void A2dpSink::DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer)
132 {
133 HILOGD("enter");
134 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
135 pimpl->observers_.Deregister(observer);
136 }
137
GetDeviceState(const BluetoothRemoteDevice &device) const138 int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const
139 {
140 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
141 if (!IS_BT_ENABLED()) {
142 HILOGE("bluetooth is off.");
143 return RET_BAD_STATUS;
144 }
145 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
146 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
147 if (!device.IsValidBluetoothRemoteDevice()) {
148 HILOGE("input parameter error.");
149 return RET_BAD_PARAM;
150 }
151
152 return proxy->GetDeviceState(RawAddress(device.GetDeviceAddr()));
153 }
154
GetDevicesByStates(std::vector<int> states) const155 std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const
156 {
157 HILOGI("enter");
158
159 if (!IS_BT_ENABLED()) {
160 HILOGE("bluetooth is off.");
161 return std::vector<BluetoothRemoteDevice>();
162 }
163
164 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
165 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(),
166 "A2dpSink proxy is nullptr");
167
168 std::vector<int32_t> convertStates;
169 for (auto state : states) {
170 convertStates.push_back(static_cast<int32_t>(state));
171 }
172 std::vector<BluetoothRemoteDevice> devices;
173 std::vector<RawAddress> rawAddrs = proxy->GetDevicesByStates(convertStates);
174 for (auto rawAddr : rawAddrs) {
175 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
176 devices.push_back(device);
177 }
178 return devices;
179 }
180
GetPlayingState(const BluetoothRemoteDevice &device) const181 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const
182 {
183 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
184 if (!IS_BT_ENABLED()) {
185 HILOGE("bluetooth is off.");
186 return RET_BAD_STATUS;
187 }
188
189 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
190 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
191
192 if (!device.IsValidBluetoothRemoteDevice()) {
193 HILOGE("input parameter error.");
194 return RET_BAD_PARAM;
195 }
196
197 int ret = RET_BAD_STATUS;
198 proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
199 return ret;
200 }
201
GetPlayingState(const BluetoothRemoteDevice &device, int &state) const202 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
203 {
204 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
205 if (!IS_BT_ENABLED()) {
206 HILOGE("bluetooth is off.");
207 return RET_BAD_STATUS;
208 }
209
210 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
211 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
212
213 if (!device.IsValidBluetoothRemoteDevice()) {
214 HILOGE("input parameter error.");
215 return RET_BAD_PARAM;
216 }
217
218 return proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
219 }
220
Connect(const BluetoothRemoteDevice &device)221 bool A2dpSink::Connect(const BluetoothRemoteDevice &device)
222 {
223 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
224 if (!IS_BT_ENABLED()) {
225 HILOGE("bluetooth is off.");
226 return false;
227 }
228
229 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
230 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
231
232 if (!device.IsValidBluetoothRemoteDevice()) {
233 HILOGE("input parameter error.");
234 return false;
235 }
236
237 int ret = proxy->Connect(RawAddress(device.GetDeviceAddr()));
238 return (ret == RET_NO_ERROR);
239 }
240
Disconnect(const BluetoothRemoteDevice &device)241 bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device)
242 {
243 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
244 if (!IS_BT_ENABLED()) {
245 HILOGE("bluetooth is off.");
246 return false;
247 }
248
249 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
250 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
251
252 if (!device.IsValidBluetoothRemoteDevice()) {
253 HILOGE("input parameter error.");
254 return false;
255 }
256
257 int ret = proxy->Disconnect(RawAddress(device.GetDeviceAddr()));
258 return (ret == RET_NO_ERROR);
259 }
260
GetProfile()261 A2dpSink *A2dpSink::GetProfile()
262 {
263 HILOGI("enter");
264 #ifdef DTFUZZ_TEST
265 static BluetoothNoDestructor<A2dpSink> service;
266 return service.get();
267 #else
268 static A2dpSink service;
269 return &service;
270 #endif
271 }
272
SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)273 bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
274 {
275 HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
276 if (!IS_BT_ENABLED()) {
277 HILOGE("bluetooth is off.");
278 return false;
279 }
280 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
281 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
282
283 if ((!device.IsValidBluetoothRemoteDevice()) ||
284 ((strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
285 (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
286 HILOGE("input parameter error.");
287 return false;
288 }
289
290 int ret = proxy->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
291 return (ret == RET_NO_ERROR);
292 }
293
GetConnectStrategy(const BluetoothRemoteDevice &device) const294 int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const
295 {
296 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
297 if (!IS_BT_ENABLED()) {
298 HILOGE("bluetooth is off.");
299 return RET_BAD_STATUS;
300 }
301 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
302 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
303
304 if (!device.IsValidBluetoothRemoteDevice()) {
305 HILOGE("input parameter error.");
306 return RET_BAD_PARAM;
307 }
308
309 int ret = proxy->GetConnectStrategy(RawAddress(device.GetDeviceAddr()));
310 return ret;
311 }
312
SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)313 bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)
314 {
315 HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue);
316 if (!IS_BT_ENABLED()) {
317 HILOGE("bluetooth is off.");
318 return false;
319 }
320 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
321 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
322
323 if (!device.IsValidBluetoothRemoteDevice()) {
324 HILOGE("input parameter error.");
325 return false;
326 }
327
328 int ret = proxy->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue);
329 return (ret == RET_NO_ERROR);
330 }
331 } // namespace Bluetooth
332 } // namespace OHOS