• 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 #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_load_system_ability.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     bool InitA2dpSinkProxy(void);
52 
53     BluetoothObserverList<A2dpSinkObserver> observers_;
54     sptr<IBluetoothA2dpSink> proxy_ = nullptr;
55     class BluetoothA2dpSinkObserverImp;
56     sptr<BluetoothA2dpSinkObserverImp> observerImp_ = nullptr;
57     class BluetoothA2dpSinkDeathRecipient;
58     sptr<BluetoothA2dpSinkDeathRecipient> deathRecipient_ = nullptr;
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)80     void OnConnectionStateChanged(const RawAddress &device, int state) override
81     {
82         HILOGD("device: %{public}s, state: %{public}d", GetEncryptAddr(device.GetAddress()).c_str(), state);
83         a2dpSink_.observers_.ForEach([device, state](std::shared_ptr<A2dpSinkObserver> observer) {
84             observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state);
85         });
86     }
87 
88 private:
89     A2dpSink::impl &a2dpSink_;
90     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkObserverImp);
91 };
92 
93 class A2dpSink::impl::BluetoothA2dpSinkDeathRecipient final : public IRemoteObject::DeathRecipient {
94 public:
BluetoothA2dpSinkDeathRecipient(A2dpSink::impl & a2dpSinkDeath)95     explicit BluetoothA2dpSinkDeathRecipient(A2dpSink::impl &a2dpSinkDeath) : a2dpSinkDeath_(a2dpSinkDeath)
96     {};
97     ~BluetoothA2dpSinkDeathRecipient() final = default;
98     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkDeathRecipient);
99 
OnRemoteDied(const wptr<IRemoteObject> & remote)100     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
101     {
102         HILOGI("enter");
103         std::lock_guard<std::mutex> lock(g_a2dpSnkProxyMutex);
104         if (!a2dpSinkDeath_.proxy_) {
105             return;
106         }
107         a2dpSinkDeath_.proxy_ = nullptr;
108     }
109 
110 private:
111     A2dpSink::impl &a2dpSinkDeath_;
112 };
113 
impl()114 A2dpSink::impl::impl()
115 {
116     HILOGI("start");
117     if (proxy_) {
118         return;
119     }
120     BluetootLoadSystemAbility::GetInstance().RegisterNotifyMsg(PROFILE_ID_A2DP_SINK);
121     if (!BluetootLoadSystemAbility::GetInstance().HasSubscribedBluetoothSystemAbility()) {
122         BluetootLoadSystemAbility::GetInstance().SubScribeBluetoothSystemAbility();
123         return;
124     }
125     InitA2dpSinkProxy();
126 };
127 
~impl()128 A2dpSink::impl::~impl()
129 {
130     HILOGI("start");
131     if (proxy_ != nullptr) {
132         proxy_->DeregisterObserver(observerImp_);
133         proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
134     }
135 }
136 
InitA2dpSinkProxy(void)137 bool A2dpSink::impl::InitA2dpSinkProxy(void)
138 {
139     std::lock_guard<std::mutex> lock(g_a2dpSnkProxyMutex);
140     if (proxy_) {
141         return true;
142     }
143     HILOGI("Enter!");
144     proxy_ = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK);
145     if (!proxy_) {
146         HILOGE("get A2dpSink proxy_ failed");
147         return false;
148     }
149 
150     deathRecipient_ = new BluetoothA2dpSinkDeathRecipient(*this);
151     if (deathRecipient_ != nullptr) {
152         proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
153     }
154 
155     observerImp_ = new (std::nothrow) BluetoothA2dpSinkObserverImp(*this);
156     if (observerImp_ != nullptr) {
157         proxy_->RegisterObserver(observerImp_);
158     }
159     return true;
160 }
161 
A2dpSink()162 A2dpSink::A2dpSink()
163 {
164     pimpl = std::make_unique<impl>();
165     if (!pimpl) {
166         HILOGE("fails: no pimpl");
167     }
168 }
169 
Init()170 void A2dpSink::Init()
171 {
172     if (!pimpl) {
173         HILOGE("fails: no pimpl");
174         return;
175     }
176     if (!pimpl->InitA2dpSinkProxy()) {
177         HILOGE("A2dpSink proxy is nullptr");
178         return;
179     }
180 }
181 
~A2dpSink()182 A2dpSink::~A2dpSink()
183 {
184     HILOGI("start");
185 }
186 
RegisterObserver(A2dpSinkObserver * observer)187 void A2dpSink::RegisterObserver(A2dpSinkObserver *observer)
188 {
189     HILOGI("enter");
190     std::shared_ptr<A2dpSinkObserver> pointer(observer, [](A2dpSinkObserver *) {});
191     pimpl->observers_.Register(pointer);
192 }
193 
DeregisterObserver(A2dpSinkObserver * observer)194 void A2dpSink::DeregisterObserver(A2dpSinkObserver *observer)
195 {
196     HILOGI("enter");
197     std::shared_ptr<A2dpSinkObserver> pointer(observer, [](A2dpSinkObserver *) {});
198     pimpl->observers_.Deregister(pointer);
199 }
200 
GetDeviceState(const BluetoothRemoteDevice & device) const201 int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const
202 {
203     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
204     if (!IS_BT_ENABLED()) {
205         HILOGE("bluetooth is off.");
206         return RET_BAD_STATUS;
207     }
208 
209     if (pimpl == nullptr || !pimpl->proxy_) {
210         HILOGE("pimpl or A2dpSink proxy is nullptr");
211         return RET_BAD_STATUS;
212     }
213 
214     if (!device.IsValidBluetoothRemoteDevice()) {
215         HILOGE("input parameter error.");
216         return RET_BAD_PARAM;
217     }
218 
219     return pimpl->proxy_->GetDeviceState(RawAddress(device.GetDeviceAddr()));
220 }
221 
GetDevicesByStates(std::vector<int> states) const222 std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const
223 {
224     HILOGI("enter");
225 
226     if (!IS_BT_ENABLED()) {
227         HILOGE("bluetooth is off.");
228         return std::vector<BluetoothRemoteDevice>();
229     }
230 
231     if (pimpl == nullptr || !pimpl->proxy_) {
232         HILOGE("pimpl or A2dpSink proxy is nullptr");
233         return std::vector<BluetoothRemoteDevice>();
234     }
235 
236     std::vector<int32_t> convertStates;
237     for (auto state : states) {
238         convertStates.push_back(static_cast<int32_t>(state));
239     }
240     std::vector<BluetoothRemoteDevice> devices;
241     std::vector<RawAddress> rawAddrs = pimpl->proxy_->GetDevicesByStates(convertStates);
242     for (auto rawAddr : rawAddrs) {
243         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
244         devices.push_back(device);
245     }
246     return devices;
247 }
248 
GetPlayingState(const BluetoothRemoteDevice & device) const249 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const
250 {
251     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
252     if (!IS_BT_ENABLED()) {
253         HILOGE("bluetooth is off.");
254         return RET_BAD_STATUS;
255     }
256 
257     if (pimpl == nullptr || !pimpl->proxy_) {
258         HILOGE("pimpl or A2dpSink proxy is nullptr");
259         return RET_BAD_STATUS;
260     }
261 
262     if (!device.IsValidBluetoothRemoteDevice()) {
263         HILOGE("input parameter error.");
264         return RET_BAD_PARAM;
265     }
266 
267     int ret = RET_BAD_STATUS;
268     pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
269     return ret;
270 }
271 
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const272 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
273 {
274     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
275     if (!IS_BT_ENABLED()) {
276         HILOGE("bluetooth is off.");
277         return RET_BAD_STATUS;
278     }
279 
280     if (pimpl == nullptr || !pimpl->proxy_) {
281         HILOGE("pimpl or A2dpSink proxy is nullptr");
282         return RET_BAD_STATUS;
283     }
284 
285     if (!device.IsValidBluetoothRemoteDevice()) {
286         HILOGE("input parameter error.");
287         return RET_BAD_PARAM;
288     }
289 
290     return pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
291 }
292 
Connect(const BluetoothRemoteDevice & device)293 bool A2dpSink::Connect(const BluetoothRemoteDevice &device)
294 {
295     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
296     if (!IS_BT_ENABLED()) {
297         HILOGE("bluetooth is off.");
298         return false;
299     }
300 
301     if (pimpl == nullptr || !pimpl->proxy_) {
302         HILOGE("pimpl or A2dpSink proxy is nullptr");
303         return false;
304     }
305 
306     if (!device.IsValidBluetoothRemoteDevice()) {
307         HILOGE("input parameter error.");
308         return false;
309     }
310 
311     int ret = pimpl->proxy_->Connect(RawAddress(device.GetDeviceAddr()));
312     return (ret == RET_NO_ERROR);
313 }
314 
Disconnect(const BluetoothRemoteDevice & device)315 bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device)
316 {
317     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
318     if (!IS_BT_ENABLED()) {
319         HILOGE("bluetooth is off.");
320         return false;
321     }
322 
323     if (pimpl == nullptr || !pimpl->proxy_) {
324         HILOGE("pimpl or A2dpSink proxy is nullptr");
325         return false;
326     }
327 
328     if (!device.IsValidBluetoothRemoteDevice()) {
329         HILOGE("input parameter error.");
330         return false;
331     }
332 
333     int ret = pimpl->proxy_->Disconnect(RawAddress(device.GetDeviceAddr()));
334     return (ret == RET_NO_ERROR);
335 }
336 
GetProfile()337 A2dpSink *A2dpSink::GetProfile()
338 {
339     HILOGI("enter");
340     static A2dpSink service;
341     return &service;
342 }
343 
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)344 bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
345 {
346     HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
347     if (!IS_BT_ENABLED()) {
348         HILOGE("bluetooth is off.");
349         return false;
350     }
351 
352     if (pimpl == nullptr || !pimpl->proxy_) {
353         HILOGE("pimpl or A2dpSink proxy is nullptr");
354         return false;
355     }
356 
357     if ((!device.IsValidBluetoothRemoteDevice()) ||
358         ((strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
359             (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
360         HILOGE("input parameter error.");
361         return false;
362     }
363 
364     int ret = pimpl->proxy_->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
365     return (ret == RET_NO_ERROR);
366 }
367 
GetConnectStrategy(const BluetoothRemoteDevice & device) const368 int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const
369 {
370     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
371     if (!IS_BT_ENABLED()) {
372         HILOGE("bluetooth is off.");
373         return RET_BAD_STATUS;
374     }
375 
376     if (pimpl == nullptr || !pimpl->proxy_) {
377         HILOGE("pimpl or A2dpSink proxy is nullptr");
378         return RET_BAD_STATUS;
379     }
380 
381     if (!device.IsValidBluetoothRemoteDevice()) {
382         HILOGE("input parameter error.");
383         return RET_BAD_PARAM;
384     }
385 
386     int ret = pimpl->proxy_->GetConnectStrategy(RawAddress(device.GetDeviceAddr()));
387     return ret;
388 }
389 
SendDelay(const BluetoothRemoteDevice & device,uint16_t delayValue)390 bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)
391 {
392     HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue);
393     if (!IS_BT_ENABLED()) {
394         HILOGE("bluetooth is off.");
395         return false;
396     }
397 
398     if (pimpl == nullptr || !pimpl->proxy_) {
399         HILOGE("pimpl or A2dpSink proxy is nullptr");
400         return false;
401     }
402 
403     if (!device.IsValidBluetoothRemoteDevice()) {
404         HILOGE("input parameter error.");
405         return false;
406     }
407 
408     int ret = pimpl->proxy_->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue);
409     return (ret == RET_NO_ERROR);
410 }
411 } // namespace Bluetooth
412 } // namespace OHOS