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