• 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_log.h"
21 #include "bluetooth_observer_list.h"
22 #include "bluetooth_remote_device.h"
23 #include "bluetooth_types.h"
24 #include "bluetooth_utils.h"
25 #include "functional"
26 #include "i_bluetooth_a2dp_sink.h"
27 #include "i_bluetooth_a2dp_sink_observer.h"
28 #include "i_bluetooth_host.h"
29 #include "if_system_ability_manager.h"
30 #include "iosfwd"
31 #include "iremote_broker.h"
32 #include "iremote_object.h"
33 #include "iservice_registry.h"
34 #include "list"
35 #include "memory"
36 #include "new"
37 #include "raw_address.h"
38 #include "refbase.h"
39 #include "string"
40 #include "system_ability_definition.h"
41 #include "vector"
42 
43 namespace OHOS {
44 namespace Bluetooth {
45 using namespace OHOS::bluetooth;
46 
47 struct A2dpSink::impl {
48     impl();
49     ~impl();
50 
51     BluetoothObserverList<A2dpSinkObserver> observers_;
52     sptr<IBluetoothA2dpSink> proxy_ = nullptr;
53     class BluetoothA2dpSinkObserverImp;
54     sptr<BluetoothA2dpSinkObserverImp> observerImp_ = nullptr;
55     class BluetoothA2dpSinkDeathRecipient;
56     sptr<BluetoothA2dpSinkDeathRecipient> deathRecipient_ = nullptr;
57 
58 private:
59     void GetProxy();
60 };
61 
62 class A2dpSink::impl::BluetoothA2dpSinkObserverImp : public BluetoothA2dpSinkObserverStub {
63 public:
BluetoothA2dpSinkObserverImp(A2dpSink::impl & a2dpSink)64     BluetoothA2dpSinkObserverImp(A2dpSink::impl &a2dpSink) : a2dpSink_(a2dpSink)
65     {};
~BluetoothA2dpSinkObserverImp()66     ~BluetoothA2dpSinkObserverImp() override
67     {};
68 
Register(std::shared_ptr<A2dpSinkObserver> & observer)69     void Register(std::shared_ptr<A2dpSinkObserver> &observer)
70     {
71         HILOGI("enter");
72         a2dpSink_.observers_.Register(observer);
73     }
74 
Deregister(std::shared_ptr<A2dpSinkObserver> & observer)75     void Deregister(std::shared_ptr<A2dpSinkObserver> &observer)
76     {
77         HILOGI("enter");
78         a2dpSink_.observers_.Deregister(observer);
79     }
80 
OnConnectionStateChanged(const RawAddress & device,int state)81     void OnConnectionStateChanged(const RawAddress &device, int state) override
82     {
83         HILOGI("device: %{public}s, state: %{public}d", GetEncryptAddr(device.GetAddress()).c_str(), state);
84         a2dpSink_.observers_.ForEach([device, state](std::shared_ptr<A2dpSinkObserver> observer) {
85             observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state);
86         });
87     }
88 
89 private:
90     A2dpSink::impl &a2dpSink_;
91     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkObserverImp);
92 };
93 
94 class A2dpSink::impl::BluetoothA2dpSinkDeathRecipient final : public IRemoteObject::DeathRecipient {
95 public:
BluetoothA2dpSinkDeathRecipient(A2dpSink::impl & a2dpSinkDeath)96     BluetoothA2dpSinkDeathRecipient(A2dpSink::impl &a2dpSinkDeath) : a2dpSinkDeath_(a2dpSinkDeath)
97     {};
98     ~BluetoothA2dpSinkDeathRecipient() final = default;
99     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkDeathRecipient);
100 
OnRemoteDied(const wptr<IRemoteObject> & remote)101     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
102     {
103         HILOGI("enter");
104         a2dpSinkDeath_.proxy_->AsObject()->RemoveDeathRecipient(a2dpSinkDeath_.deathRecipient_);
105         a2dpSinkDeath_.proxy_ = nullptr;
106     }
107 
108 private:
109     A2dpSink::impl &a2dpSinkDeath_;
110 };
111 
impl()112 A2dpSink::impl::impl()
113 {
114     HILOGI("start");
115     GetProxy();
116     if (proxy_ == nullptr) {
117         HILOGI("get proxy_ failed");
118         return;
119     }
120 
121     deathRecipient_ = new BluetoothA2dpSinkDeathRecipient(*this);
122     proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
123 
124     observerImp_ = new (std::nothrow) BluetoothA2dpSinkObserverImp(*this);
125     if (observerImp_ == nullptr) {
126         HILOGI("get observerImp_ failed");
127         return;
128     }
129     proxy_->RegisterObserver(observerImp_);
130 };
131 
~impl()132 A2dpSink::impl::~impl()
133 {
134     HILOGI("start");
135     if (proxy_ != nullptr) {
136         proxy_->DeregisterObserver(observerImp_);
137         proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
138     }
139 }
140 
GetProxy()141 void A2dpSink::impl::GetProxy()
142 {
143     HILOGI("start");
144     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
145     if (!samgr) {
146         HILOGE("error: no samgr");
147         return;
148     }
149 
150     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
151     if (!hostRemote) {
152         HILOGE("failed: no hostRemote");
153         return;
154     }
155 
156     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
157     if (!hostProxy) {
158         HILOGE("error: host no proxy");
159         return;
160     }
161 
162     sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_A2DP_SINK);
163     if (!remote) {
164         HILOGE("error: no remote");
165         return;
166     }
167 
168     proxy_ = iface_cast<IBluetoothA2dpSink>(remote);
169     if (!proxy_) {
170         HILOGE("error: no proxy");
171         return;
172     }
173 }
174 
A2dpSink()175 A2dpSink::A2dpSink()
176 {
177     pimpl = std::make_unique<impl>();
178     if (!pimpl) {
179         HILOGE("fails: no pimpl");
180     }
181 }
182 
~A2dpSink()183 A2dpSink::~A2dpSink()
184 {
185     HILOGI("start");
186 }
187 
RegisterObserver(A2dpSinkObserver * observer)188 void A2dpSink::RegisterObserver(A2dpSinkObserver *observer)
189 {
190     HILOGI("enter");
191     std::shared_ptr<A2dpSinkObserver> pointer(observer, [](A2dpSinkObserver *) {});
192     pimpl->observers_.Register(pointer);
193 }
194 
DeregisterObserver(A2dpSinkObserver * observer)195 void A2dpSink::DeregisterObserver(A2dpSinkObserver *observer)
196 {
197     HILOGI("enter");
198     std::shared_ptr<A2dpSinkObserver> pointer(observer, [](A2dpSinkObserver *) {});
199     pimpl->observers_.Deregister(pointer);
200 }
201 
GetDeviceState(const BluetoothRemoteDevice & device) const202 int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const
203 {
204     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
205 
206     if (!device.IsValidBluetoothRemoteDevice()) {
207         HILOGI("input parameter error.");
208         return RET_BAD_STATUS;
209     }
210 
211     int ret = RET_BAD_STATUS;
212     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
213         ret = pimpl->proxy_->GetDeviceState(RawAddress(device.GetDeviceAddr()));
214     } else {
215         HILOGI("proxy or bt disable.");
216     }
217 
218     return ret;
219 }
220 
GetDevicesByStates(std::vector<int> states) const221 std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const
222 {
223     HILOGI("enter");
224     std::vector<BluetoothRemoteDevice> devices;
225 
226     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
227         std::vector<int32_t> convertStates;
228         for (auto state : states) {
229             convertStates.push_back(static_cast<int32_t>(state));
230         }
231         std::vector<RawAddress> rawAddrs;
232         rawAddrs = pimpl->proxy_->GetDevicesByStates(convertStates);
233 
234         for (auto rawAddr : rawAddrs) {
235             BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
236             devices.push_back(device);
237         }
238     }
239 
240     return devices;
241 }
242 
GetPlayingState(const BluetoothRemoteDevice & device) const243 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const
244 {
245     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
246 
247     if (!device.IsValidBluetoothRemoteDevice()) {
248         HILOGI("input parameter error.");
249         return RET_BAD_STATUS;
250     }
251 
252     int ret = RET_BAD_STATUS;
253     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
254         pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
255     } else {
256         HILOGI("proxy or bt disable.");
257     }
258 
259     return ret;
260 }
261 
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const262 int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
263 {
264     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
265 
266     if (!device.IsValidBluetoothRemoteDevice()) {
267         HILOGI("input parameter error.");
268         return BT_ERR_INVALID_PARAM;
269     }
270 
271     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
272         return pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
273     } else {
274         HILOGI("proxy or bt disable.");
275         return BT_ERR_SERVICE_DISCONNECTED;
276     }
277 }
278 
Connect(const BluetoothRemoteDevice & device)279 bool A2dpSink::Connect(const BluetoothRemoteDevice &device)
280 {
281     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
282 
283     if (!device.IsValidBluetoothRemoteDevice()) {
284         HILOGI("input parameter error.");
285         return false;
286     }
287 
288     int ret = RET_NO_ERROR;
289     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
290         ret = pimpl->proxy_->Connect(RawAddress(device.GetDeviceAddr()));
291     } else {
292         HILOGI("proxy or bt disable.");
293         return false;
294     }
295     return (ret == RET_NO_ERROR);
296 }
297 
Disconnect(const BluetoothRemoteDevice & device)298 bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device)
299 {
300     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
301 
302     if (!device.IsValidBluetoothRemoteDevice()) {
303         HILOGI("input parameter error.");
304         return false;
305     }
306 
307     int ret = RET_NO_ERROR;
308     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
309         ret = pimpl->proxy_->Disconnect(RawAddress(device.GetDeviceAddr()));
310     } else {
311         HILOGI("proxy or bt disable.");
312         return false;
313     }
314     return (ret == RET_NO_ERROR);
315 }
316 
GetProfile()317 A2dpSink *A2dpSink::GetProfile()
318 {
319     HILOGI("enter");
320     static A2dpSink service;
321     return &service;
322 }
323 
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)324 bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
325 {
326     HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
327 
328     if ((!device.IsValidBluetoothRemoteDevice()) || (
329         (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
330         (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
331         HILOGI("input parameter error.");
332         return false;
333     }
334 
335     int ret = RET_NO_ERROR;
336     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
337         ret = pimpl->proxy_->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
338     } else {
339         HILOGI("proxy or bt disable.");
340         return false;
341     }
342 
343     return (ret == RET_NO_ERROR);
344 }
345 
GetConnectStrategy(const BluetoothRemoteDevice & device) const346 int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const
347 {
348     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
349 
350     if (!device.IsValidBluetoothRemoteDevice()) {
351         HILOGI("input parameter error.");
352         return RET_BAD_PARAM;
353     }
354 
355     int ret = RET_NO_ERROR;
356     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
357         ret = pimpl->proxy_->GetConnectStrategy(RawAddress(device.GetDeviceAddr()));
358     } else {
359         HILOGI("proxy or bt disable.");
360         return false;
361     }
362     return ret;
363 }
364 
SendDelay(const BluetoothRemoteDevice & device,uint16_t delayValue)365 bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue)
366 {
367     HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue);
368 
369     if (!device.IsValidBluetoothRemoteDevice()) {
370         HILOGI("input parameter error.");
371         return false;
372     }
373 
374     int ret = RET_NO_ERROR;
375     if (pimpl->proxy_ != nullptr && IS_BT_ENABLED()) {
376         ret = pimpl->proxy_->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue);
377     } else {
378         HILOGI("proxy or bt disable.");
379         return false;
380     }
381 
382     return (ret == RET_NO_ERROR);
383 }
384 }  // namespace Bluetooth
385 }  // namespace OHOS