• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     CHECK_AND_RETURN_LOG(observer != nullptr, "observer is null.");
133     pimpl->observers_.Register(observer);
134 }
135 
DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer)136 void A2dpSink::DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer)
137 {
138     HILOGD("enter");
139     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
140     pimpl->observers_.Deregister(observer);
141 }
142 
GetDeviceState(const BluetoothRemoteDevice & device) const143 int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const
144 {
145     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
146     if (!IS_BT_ENABLED()) {
147         HILOGE("bluetooth is off.");
148         return RET_BAD_STATUS;
149     }
150     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
151     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
152     if (!device.IsValidBluetoothRemoteDevice()) {
153         HILOGE("input parameter error.");
154         return RET_BAD_PARAM;
155     }
156 
157     return proxy->GetDeviceState(RawAddress(device.GetDeviceAddr()));
158 }
159 
GetDevicesByStates(std::vector<int> states) const160 std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const
161 {
162     HILOGI("enter");
163 
164     if (!IS_BT_ENABLED()) {
165         HILOGE("bluetooth is off.");
166         return std::vector<BluetoothRemoteDevice>();
167     }
168 
169     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
170     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(),
171         "A2dpSink proxy is nullptr");
172 
173     std::vector<int32_t> convertStates;
174     for (auto state : states) {
175         convertStates.push_back(static_cast<int32_t>(state));
176     }
177     std::vector<BluetoothRemoteDevice> devices;
178     std::vector<RawAddress> rawAddrs = proxy->GetDevicesByStates(convertStates);
179     for (auto rawAddr : rawAddrs) {
180         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
181         devices.push_back(device);
182     }
183     return devices;
184 }
185 
GetPlayingState(const BluetoothRemoteDevice & device) const186 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const
187 {
188     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
189     if (!IS_BT_ENABLED()) {
190         HILOGE("bluetooth is off.");
191         return RET_BAD_STATUS;
192     }
193 
194     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
195     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
196 
197     if (!device.IsValidBluetoothRemoteDevice()) {
198         HILOGE("input parameter error.");
199         return RET_BAD_PARAM;
200     }
201 
202     int ret = RET_BAD_STATUS;
203     proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
204     return ret;
205 }
206 
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const207 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
208 {
209     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
210     if (!IS_BT_ENABLED()) {
211         HILOGE("bluetooth is off.");
212         return RET_BAD_STATUS;
213     }
214 
215     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
216     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
217 
218     if (!device.IsValidBluetoothRemoteDevice()) {
219         HILOGE("input parameter error.");
220         return RET_BAD_PARAM;
221     }
222 
223     return proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
224 }
225 
Connect(const BluetoothRemoteDevice & device)226 bool A2dpSink::Connect(const BluetoothRemoteDevice &device)
227 {
228     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
229     if (!IS_BT_ENABLED()) {
230         HILOGE("bluetooth is off.");
231         return false;
232     }
233 
234     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
235     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
236 
237     if (!device.IsValidBluetoothRemoteDevice()) {
238         HILOGE("input parameter error.");
239         return false;
240     }
241 
242     int ret = proxy->Connect(RawAddress(device.GetDeviceAddr()));
243     return (ret == RET_NO_ERROR);
244 }
245 
Disconnect(const BluetoothRemoteDevice & device)246 bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device)
247 {
248     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
249     if (!IS_BT_ENABLED()) {
250         HILOGE("bluetooth is off.");
251         return false;
252     }
253 
254     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
255     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
256 
257     if (!device.IsValidBluetoothRemoteDevice()) {
258         HILOGE("input parameter error.");
259         return false;
260     }
261 
262     int ret = proxy->Disconnect(RawAddress(device.GetDeviceAddr()));
263     return (ret == RET_NO_ERROR);
264 }
265 
GetProfile()266 A2dpSink *A2dpSink::GetProfile()
267 {
268     HILOGI("enter");
269 #ifdef DTFUZZ_TEST
270     static BluetoothNoDestructor<A2dpSink> service;
271     return service.get();
272 #else
273     static A2dpSink service;
274     return &service;
275 #endif
276 }
277 
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)278 bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
279 {
280     HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
281     if (!IS_BT_ENABLED()) {
282         HILOGE("bluetooth is off.");
283         return false;
284     }
285     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
286     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
287 
288     if ((!device.IsValidBluetoothRemoteDevice()) ||
289         ((strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
290             (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
291         HILOGE("input parameter error.");
292         return false;
293     }
294 
295     int ret = proxy->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
296     return (ret == RET_NO_ERROR);
297 }
298 
GetConnectStrategy(const BluetoothRemoteDevice & device) const299 int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const
300 {
301     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
302     if (!IS_BT_ENABLED()) {
303         HILOGE("bluetooth is off.");
304         return RET_BAD_STATUS;
305     }
306     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
307     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr");
308 
309     if (!device.IsValidBluetoothRemoteDevice()) {
310         HILOGE("input parameter error.");
311         return RET_BAD_PARAM;
312     }
313 
314     int ret = proxy->GetConnectStrategy(RawAddress(device.GetDeviceAddr()));
315     return ret;
316 }
317 
SendDelay(const BluetoothRemoteDevice & device,uint16_t delayValue)318 bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)
319 {
320     HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue);
321     if (!IS_BT_ENABLED()) {
322         HILOGE("bluetooth is off.");
323         return false;
324     }
325     sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
326     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr");
327 
328     if (!device.IsValidBluetoothRemoteDevice()) {
329         HILOGE("input parameter error.");
330         return false;
331     }
332 
333     int ret = proxy->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue);
334     return (ret == RET_NO_ERROR);
335 }
336 } // namespace Bluetooth
337 } // namespace OHOS