• 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 
16 #include "bluetooth_a2dp_src.h"
17 #include <unistd.h>
18 #include "bluetooth_a2dp_codec.h"
19 #include "bluetooth_a2dp_src_proxy.h"
20 #include "bluetooth_a2dp_src_observer_stub.h"
21 #include "bluetooth_device.h"
22 #include "bluetooth_host_proxy.h"
23 #include "bluetooth_load_system_ability.h"
24 #include "bluetooth_observer_list.h"
25 #include "raw_address.h"
26 #include "bluetooth_def.h"
27 #include "bluetooth_host.h"
28 
29 #include "bluetooth_log.h"
30 #include "bluetooth_utils.h"
31 #include "iservice_registry.h"
32 #include "system_ability_definition.h"
33 
34 namespace OHOS {
35 namespace Bluetooth {
36 using namespace OHOS::bluetooth;
37 std::mutex g_a2dpProxyMutex;
38 struct A2dpSource::impl {
39     impl();
40     ~impl();
41     bool InitA2dpSrcProxy(void);
42 
43     BluetoothObserverList<A2dpSourceObserver> observers_;
44     sptr<IBluetoothA2dpSrc> proxy_ = nullptr;
45     class BluetoothA2dpSourceObserverImp;
46     sptr<BluetoothA2dpSourceObserverImp> observerImp_ = nullptr;
47     class BluetoothA2dpSourceDeathRecipient;
48     sptr<BluetoothA2dpSourceDeathRecipient> deathRecipient_ = nullptr;
49 };
50 
51 class A2dpSource::impl::BluetoothA2dpSourceObserverImp : public BluetoothA2dpSrcObserverStub {
52 public:
BluetoothA2dpSourceObserverImp(A2dpSource::impl & a2dpSource)53     explicit BluetoothA2dpSourceObserverImp(A2dpSource::impl &a2dpSource) : a2dpSource_(a2dpSource) {};
~BluetoothA2dpSourceObserverImp()54     ~BluetoothA2dpSourceObserverImp() override{};
55 
Register(std::shared_ptr<A2dpSourceObserver> & observer)56     void Register(std::shared_ptr<A2dpSourceObserver> &observer)
57     {
58         HILOGI("enter");
59         a2dpSource_.observers_.Register(observer);
60     }
61 
Deregister(std::shared_ptr<A2dpSourceObserver> & observer)62     void Deregister(std::shared_ptr<A2dpSourceObserver> &observer)
63     {
64         HILOGI("enter");
65         a2dpSource_.observers_.Deregister(observer);
66     }
67 
OnConnectionStateChanged(const RawAddress & device,int state)68     void OnConnectionStateChanged(const RawAddress &device, int state) override
69     {
70         HILOGD("a2dpSrc conn state, device: %{public}s, state: %{public}s",
71             GetEncryptAddr((device).GetAddress()).c_str(), GetProfileConnStateName(state).c_str());
72         a2dpSource_.observers_.ForEach([device, state](std::shared_ptr<A2dpSourceObserver> observer) {
73             observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state);
74         });
75     }
76 
OnPlayingStatusChanged(const RawAddress & device,int playingState,int error)77     void OnPlayingStatusChanged(const RawAddress &device, int playingState, int error) override
78     {
79         HILOGI("device: %{public}s, playingState: %{public}d, error: %{public}d",
80             GetEncryptAddr(device.GetAddress()).c_str(), playingState, error);
81         a2dpSource_.observers_.ForEach([device, playingState, error](std::shared_ptr<A2dpSourceObserver> observer) {
82             observer->OnPlayingStatusChanged(BluetoothRemoteDevice(device.GetAddress(), 0), playingState, error);
83         });
84     }
85 
OnConfigurationChanged(const RawAddress & device,const BluetoothA2dpCodecInfo & info,int error)86     void OnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error) override
87     {
88         HILOGI("device: %{public}s, error: %{public}d", GetEncryptAddr(device.GetAddress()).c_str(), error);
89         a2dpSource_.observers_.ForEach([device, info, error](std::shared_ptr<A2dpSourceObserver> observer) {
90             A2dpCodecInfo codecInfo;
91 
92             codecInfo.bitsPerSample = info.bitsPerSample;
93             codecInfo.channelMode = info.channelMode;
94             codecInfo.codecPriority = info.codecPriority;
95             codecInfo.codecType = info.codecType;
96             codecInfo.sampleRate = info.sampleRate;
97 
98             observer->OnConfigurationChanged(BluetoothRemoteDevice(device.GetAddress(), 0), codecInfo, error);
99         });
100     };
101 
102 private:
103     A2dpSource::impl &a2dpSource_;
104     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSourceObserverImp);
105 };
106 
107 class A2dpSource::impl::BluetoothA2dpSourceDeathRecipient final : public IRemoteObject::DeathRecipient {
108 public:
BluetoothA2dpSourceDeathRecipient(A2dpSource::impl & a2dpSrcDeath)109     explicit BluetoothA2dpSourceDeathRecipient(A2dpSource::impl &a2dpSrcDeath) : a2dpSrcDeath_(a2dpSrcDeath)
110     {};
111     ~BluetoothA2dpSourceDeathRecipient() final = default;
112     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSourceDeathRecipient);
113 
OnRemoteDied(const wptr<IRemoteObject> & remote)114     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
115     {
116         HILOGI("enter");
117         std::lock_guard<std::mutex> lock(g_a2dpProxyMutex);
118         if (!a2dpSrcDeath_.proxy_) {
119             return;
120         }
121         a2dpSrcDeath_.proxy_ = nullptr;
122     }
123 
124 private:
125     A2dpSource::impl &a2dpSrcDeath_;
126 };
127 
impl()128 A2dpSource::impl::impl()
129 {
130     if (proxy_) {
131         return;
132     }
133     BluetootLoadSystemAbility::GetInstance().RegisterNotifyMsg(PROFILE_ID_A2DP_SRC);
134     if (!BluetootLoadSystemAbility::GetInstance().HasSubscribedBluetoothSystemAbility()) {
135         BluetootLoadSystemAbility::GetInstance().SubScribeBluetoothSystemAbility();
136         return;
137     }
138     InitA2dpSrcProxy();
139 };
140 
~impl()141 A2dpSource::impl::~impl()
142 {
143     HILOGI("start");
144     if (proxy_ != nullptr) {
145         proxy_->DeregisterObserver(observerImp_);
146         proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
147     }
148 }
149 
InitA2dpSrcProxy(void)150 bool A2dpSource::impl::InitA2dpSrcProxy(void)
151 {
152     std::lock_guard<std::mutex> lock(g_a2dpProxyMutex);
153     if (proxy_) {
154         return true;
155     }
156     HILOGI("enter");
157     proxy_ = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
158     if (!proxy_) {
159         HILOGE("get A2dpSource proxy_ failed");
160         return false;
161     }
162 
163     deathRecipient_ = new BluetoothA2dpSourceDeathRecipient(*this);
164     if (deathRecipient_ != nullptr) {
165         proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
166     }
167 
168     observerImp_ = new (std::nothrow) BluetoothA2dpSourceObserverImp(*this);
169     if (observerImp_ != nullptr) {
170         proxy_->RegisterObserver(observerImp_);
171     }
172     return true;
173 }
174 
A2dpSource()175 A2dpSource::A2dpSource()
176 {
177     pimpl = std::make_unique<impl>();
178     if (!pimpl) {
179         HILOGE("fails: no pimpl");
180     }
181 }
182 
~A2dpSource()183 A2dpSource::~A2dpSource()
184 {
185     HILOGI("start");
186 }
187 
Init()188 void A2dpSource::Init()
189 {
190     if (!pimpl) {
191         HILOGE("fails: no pimpl");
192         return;
193     }
194     if (!pimpl->InitA2dpSrcProxy()) {
195         HILOGE("A2dpSrc proxy is nullptr");
196         return;
197     }
198 }
199 
RegisterObserver(A2dpSourceObserver * observer)200 void A2dpSource::RegisterObserver(A2dpSourceObserver *observer)
201 {
202     HILOGI("enter");
203     std::shared_ptr<A2dpSourceObserver> pointer(observer, [](A2dpSourceObserver *) {});
204     pimpl->observers_.Register(pointer);
205 }
206 
DeregisterObserver(A2dpSourceObserver * observer)207 void A2dpSource::DeregisterObserver(A2dpSourceObserver *observer)
208 {
209     HILOGI("enter");
210     std::shared_ptr<A2dpSourceObserver> pointer(observer, [](A2dpSourceObserver *) {});
211     pimpl->observers_.Deregister(pointer);
212 }
213 
GetDevicesByStates(const std::vector<int> & states,std::vector<BluetoothRemoteDevice> & devices) const214 int A2dpSource::GetDevicesByStates(const std::vector<int> &states, std::vector<BluetoothRemoteDevice> &devices) const
215 {
216     HILOGI("enter");
217     if (!IS_BT_ENABLED()) {
218         HILOGE("bluetooth is off.");
219         return BT_ERR_INVALID_STATE;
220     }
221 
222     if (pimpl == nullptr || !pimpl->proxy_) {
223         HILOGE("pimpl or a2dpSrc proxy is nullptr");
224         return BT_ERR_UNAVAILABLE_PROXY;
225     }
226 
227     std::vector<int32_t> convertStates;
228     for (auto state : states) {
229         convertStates.push_back(static_cast<int32_t>(state));
230     }
231 
232     std::vector<RawAddress> rawAddrs;
233     int ret = pimpl->proxy_->GetDevicesByStates(convertStates, rawAddrs);
234     if (ret != BT_NO_ERROR) {
235         HILOGE("GetDevicesByStates return error.");
236         return ret;
237     }
238     for (auto rawAddr : rawAddrs) {
239         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
240         devices.push_back(device);
241     }
242     return BT_NO_ERROR;
243 }
244 
GetDeviceState(const BluetoothRemoteDevice & device,int & state) const245 int A2dpSource::GetDeviceState(const BluetoothRemoteDevice &device, int &state) const
246 {
247     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
248     if (!IS_BT_ENABLED()) {
249         HILOGE("bluetooth is off.");
250         return BT_ERR_INVALID_STATE;
251     }
252 
253     if (pimpl == nullptr || !pimpl->proxy_) {
254         HILOGE("pimpl or a2dpSrc proxy is nullptr");
255         return BT_ERR_UNAVAILABLE_PROXY;
256     }
257 
258     if (!device.IsValidBluetoothRemoteDevice()) {
259         HILOGE("input parameter error.");
260         return BT_ERR_INVALID_PARAM;
261     }
262 
263     int ret = pimpl->proxy_->GetDeviceState(RawAddress(device.GetDeviceAddr()), state);
264     HILOGI("state: %{public}d", ret);
265     return ret;
266 }
267 
GetPlayingState(const BluetoothRemoteDevice & device) const268 int32_t A2dpSource::GetPlayingState(const BluetoothRemoteDevice &device) const
269 {
270     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
271     if (!IS_BT_ENABLED()) {
272         HILOGE("bluetooth is off.");
273         return RET_BAD_STATUS;
274     }
275 
276     if (pimpl == nullptr || !pimpl->proxy_) {
277         HILOGE("pimpl or a2dpSrc proxy is nullptr");
278         return RET_BAD_STATUS;
279     }
280 
281     if (!device.IsValidBluetoothRemoteDevice()) {
282         HILOGE("input parameter error.");
283         return RET_BAD_PARAM;
284     }
285 
286     int ret = RET_NO_ERROR;
287     pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
288     HILOGI("state: %{public}d", ret);
289     return ret;
290 }
291 
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const292 int32_t A2dpSource::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
293 {
294     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
295     if (!IS_BT_ENABLED()) {
296         HILOGE("bluetooth is off.");
297         return BT_ERR_INVALID_STATE;
298     }
299 
300     if (pimpl == nullptr || !pimpl->proxy_) {
301         HILOGE("pimpl or a2dpSrc proxy is nullptr");
302         return BT_ERR_UNAVAILABLE_PROXY;
303     }
304 
305     if (!device.IsValidBluetoothRemoteDevice()) {
306         HILOGE("input parameter error.");
307         return BT_ERR_INVALID_PARAM;
308     }
309 
310     return pimpl->proxy_->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
311 }
312 
Connect(const BluetoothRemoteDevice & device)313 int32_t A2dpSource::Connect(const BluetoothRemoteDevice &device)
314 {
315     HILOGI("a2dp connect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
316     if (!IS_BT_ENABLED()) {
317         HILOGE("bluetooth is off.");
318         return BT_ERR_INVALID_STATE;
319     }
320 
321     if (pimpl == nullptr || !pimpl->proxy_) {
322         HILOGE("pimpl or a2dpSrc proxy is nullptr");
323         return BT_ERR_UNAVAILABLE_PROXY;
324     }
325 
326     if (!device.IsValidBluetoothRemoteDevice()) {
327         HILOGE("input parameter error.");
328         return BT_ERR_INVALID_PARAM;
329     }
330 
331     int cod = 0;
332     int32_t err = device.GetDeviceClass(cod);
333     if (err != BT_NO_ERROR) {
334         HILOGE("GetDeviceClass Failed.");
335         return BT_ERR_INTERNAL_ERROR;
336     }
337     BluetoothDeviceClass devClass = BluetoothDeviceClass(cod);
338     if (!devClass.IsProfileSupported(BluetoothDevice::PROFILE_A2DP)) {
339         HILOGE("a2dp connect failed. The remote device does not support A2DP service.");
340         return BT_ERR_INTERNAL_ERROR;
341     }
342 
343     return pimpl->proxy_->Connect(RawAddress(device.GetDeviceAddr()));
344 }
345 
Disconnect(const BluetoothRemoteDevice & device)346 int32_t A2dpSource::Disconnect(const BluetoothRemoteDevice &device)
347 {
348     HILOGI("a2dp disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
349     if (!IS_BT_ENABLED()) {
350         HILOGE("bluetooth is off.");
351         return BT_ERR_INVALID_STATE;
352     }
353 
354     if (pimpl == nullptr || !pimpl->proxy_) {
355         HILOGE("pimpl or a2dpSrc proxy is nullptr");
356         return BT_ERR_UNAVAILABLE_PROXY;
357     }
358 
359     if (!device.IsValidBluetoothRemoteDevice()) {
360         HILOGE("input parameter error.");
361         return BT_ERR_INVALID_PARAM;
362     }
363 
364     return pimpl->proxy_->Disconnect(RawAddress(device.GetDeviceAddr()));
365 }
366 
GetProfile()367 A2dpSource *A2dpSource::GetProfile()
368 {
369     HILOGI("enter");
370     static A2dpSource service;
371     return &service;
372 }
373 
SetActiveSinkDevice(const BluetoothRemoteDevice & device)374 int A2dpSource::SetActiveSinkDevice(const BluetoothRemoteDevice &device)
375 {
376     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
377     if (!IS_BT_ENABLED()) {
378         HILOGE("bluetooth is off.");
379         return RET_BAD_STATUS;
380     }
381 
382     if (pimpl == nullptr || !pimpl->proxy_) {
383         HILOGE("pimpl or a2dpSrc proxy is nullptr");
384         return RET_BAD_STATUS;
385     }
386 
387     if (!device.IsValidBluetoothRemoteDevice()) {
388         HILOGE("input parameter error.");
389         return RET_BAD_PARAM;
390     }
391 
392     return pimpl->proxy_->SetActiveSinkDevice(RawAddress(device.GetDeviceAddr()));
393 }
394 
GetActiveSinkDevice() const395 const BluetoothRemoteDevice &A2dpSource::GetActiveSinkDevice() const
396 {
397     HILOGI("enter");
398     static BluetoothRemoteDevice deviceInfo;
399     if (!IS_BT_ENABLED()) {
400         HILOGE("bluetooth is off.");
401         return deviceInfo;
402     }
403 
404     if (pimpl == nullptr || !pimpl->proxy_) {
405         HILOGE("pimpl or a2dpSrc proxy is nullptr");
406         return deviceInfo;
407     }
408 
409     BluetoothRawAddress rawAddress = pimpl->proxy_->GetActiveSinkDevice();
410     deviceInfo = BluetoothRemoteDevice(rawAddress.GetAddress(), 0);
411     return deviceInfo;
412 }
413 
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)414 int A2dpSource::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
415 {
416     HILOGI("device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
417     if (!IS_BT_ENABLED()) {
418         HILOGE("bluetooth is off.");
419         return BT_ERR_INVALID_STATE;
420     }
421 
422     if (pimpl == nullptr || !pimpl->proxy_) {
423         HILOGE("pimpl or a2dpSrc proxy is nullptr");
424         return BT_ERR_UNAVAILABLE_PROXY;
425     }
426 
427     if ((!device.IsValidBluetoothRemoteDevice()) || (
428         (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
429         (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
430         HILOGI("input parameter error.");
431         return BT_ERR_INVALID_PARAM;
432     }
433 
434     return pimpl->proxy_->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
435 }
436 
GetConnectStrategy(const BluetoothRemoteDevice & device,int & strategy) const437 int A2dpSource::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
438 {
439     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
440     if (!IS_BT_ENABLED()) {
441         HILOGE("bluetooth is off.");
442         return BT_ERR_INVALID_STATE;
443     }
444 
445     if (pimpl == nullptr || !pimpl->proxy_) {
446         HILOGE("pimpl or a2dpSrc proxy is nullptr");
447         return BT_ERR_INVALID_STATE;
448     }
449 
450     if (!device.IsValidBluetoothRemoteDevice()) {
451         HILOGI("input parameter error.");
452         return BT_ERR_INVALID_PARAM;
453     }
454 
455     return pimpl->proxy_->GetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
456 }
457 
GetCodecStatus(const BluetoothRemoteDevice & device) const458 A2dpCodecStatus A2dpSource::GetCodecStatus(const BluetoothRemoteDevice &device) const
459 {
460     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
461     A2dpCodecStatus ret;
462     if (!IS_BT_ENABLED()) {
463         HILOGE("bluetooth is off.");
464         return ret;
465     }
466 
467     if (pimpl == nullptr || !pimpl->proxy_) {
468         HILOGE("pimpl or a2dpSrc proxy is nullptr");
469         return ret;
470     }
471 
472     if (!device.IsValidBluetoothRemoteDevice()) {
473         HILOGE("input parameter error.");
474         return ret;
475     }
476 
477     BluetoothA2dpCodecStatus codecStatus = pimpl->proxy_->GetCodecStatus(RawAddress(device.GetDeviceAddr()));
478     ret.codecInfo.codecType = codecStatus.codecInfo.codecType;
479     ret.codecInfo.sampleRate = codecStatus.codecInfo.sampleRate;
480     ret.codecInfo.channelMode = codecStatus.codecInfo.channelMode;
481     ret.codecInfo.codecPriority = codecStatus.codecInfo.codecPriority;
482     ret.codecInfo.bitsPerSample = codecStatus.codecInfo.bitsPerSample;
483 
484     A2dpCodecInfo serviceInfo;
485     for (auto it = codecStatus.codecInfoConfirmCap.begin(); it != codecStatus.codecInfoConfirmCap.end(); it++) {
486         serviceInfo.codecType = it->codecType;
487         serviceInfo.sampleRate = it->sampleRate;
488         serviceInfo.channelMode = it->channelMode;
489         serviceInfo.codecPriority = it->codecPriority;
490         serviceInfo.bitsPerSample = it->bitsPerSample;
491         ret.codecInfoConfirmedCap.push_back(serviceInfo);
492     }
493 
494     for (auto it = codecStatus.codecInfoLocalCap.begin(); it != codecStatus.codecInfoLocalCap.end(); it++) {
495         serviceInfo.codecType = it->codecType;
496         serviceInfo.sampleRate = it->sampleRate;
497         serviceInfo.channelMode = it->channelMode;
498         serviceInfo.codecPriority = it->codecPriority;
499         serviceInfo.bitsPerSample = it->bitsPerSample;
500         ret.codecInfoLocalCap.push_back(serviceInfo);
501     }
502     return ret;
503 }
504 
SetCodecPreference(const BluetoothRemoteDevice & device,const A2dpCodecInfo & info)505 int A2dpSource::SetCodecPreference(const BluetoothRemoteDevice &device, const A2dpCodecInfo &info)
506 {
507     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
508     if (!IS_BT_ENABLED()) {
509         HILOGE("bluetooth is off.");
510         return RET_BAD_STATUS;
511     }
512 
513     if (pimpl == nullptr || !pimpl->proxy_) {
514         HILOGE("pimpl or a2dpSrc proxy is nullptr");
515         return RET_BAD_STATUS;
516     }
517 
518     if (!device.IsValidBluetoothRemoteDevice()) {
519         HILOGE("input parameter error.");
520         return RET_BAD_PARAM;
521     }
522 
523     BluetoothA2dpCodecInfo serviceInfo;
524     serviceInfo.codecType = info.codecType;
525     serviceInfo.sampleRate = info.sampleRate;
526     serviceInfo.channelMode = info.channelMode;
527     serviceInfo.bitsPerSample = info.bitsPerSample;
528     serviceInfo.codecPriority = info.codecPriority;
529     serviceInfo.codecSpecific1 = info.codecSpecific1;
530     serviceInfo.codecSpecific2 = info.codecSpecific2;
531     serviceInfo.codecSpecific3 = info.codecSpecific3;
532     serviceInfo.codecSpecific4 = info.codecSpecific4;
533 
534     return pimpl->proxy_->SetCodecPreference(RawAddress(device.GetDeviceAddr()), serviceInfo);
535 }
536 
SwitchOptionalCodecs(const BluetoothRemoteDevice & device,bool isEnable)537 void A2dpSource::SwitchOptionalCodecs(const BluetoothRemoteDevice &device, bool isEnable)
538 {
539     HILOGI("enter");
540     if (!IS_BT_ENABLED()) {
541         HILOGE("bluetooth is off.");
542         return;
543     }
544 
545     if (pimpl == nullptr || !pimpl->proxy_) {
546         HILOGE("pimpl or a2dpSrc proxy is nullptr");
547         return;
548     }
549 
550     if (!device.IsValidBluetoothRemoteDevice()) {
551         HILOGE("input parameter error.");
552         return;
553     }
554 
555     pimpl->proxy_->SwitchOptionalCodecs(RawAddress(device.GetDeviceAddr()), isEnable);
556 }
557 
GetOptionalCodecsSupportState(const BluetoothRemoteDevice & device) const558 int A2dpSource::GetOptionalCodecsSupportState(const BluetoothRemoteDevice &device) const
559 {
560     HILOGI("enter");
561     if (!IS_BT_ENABLED()) {
562         HILOGE("bluetooth is off.");
563         return RET_BAD_STATUS;
564     }
565 
566     if (pimpl == nullptr || !pimpl->proxy_) {
567         HILOGE("pimpl or a2dpSrc proxy is nullptr");
568         return RET_BAD_STATUS;
569     }
570 
571     if (!device.IsValidBluetoothRemoteDevice()) {
572         HILOGE("input parameter error.");
573         return RET_BAD_PARAM;
574     }
575 
576     return pimpl->proxy_->GetOptionalCodecsSupportState(RawAddress(device.GetDeviceAddr()));
577 }
578 
StartPlaying(const BluetoothRemoteDevice & device)579 int A2dpSource::StartPlaying(const BluetoothRemoteDevice &device)
580 {
581     HILOGI("enter");
582     if (!IS_BT_ENABLED()) {
583         HILOGE("bluetooth is off.");
584         return RET_BAD_STATUS;
585     }
586 
587     if (pimpl == nullptr || !pimpl->proxy_) {
588         HILOGE("pimpl or a2dpSrc proxy is nullptr");
589         return RET_BAD_STATUS;
590     }
591 
592     if (!device.IsValidBluetoothRemoteDevice()) {
593         HILOGE("input parameter error.");
594         return RET_BAD_PARAM;
595     }
596 
597     return pimpl->proxy_->StartPlaying(RawAddress(device.GetDeviceAddr()));
598 }
599 
SuspendPlaying(const BluetoothRemoteDevice & device)600 int A2dpSource::SuspendPlaying(const BluetoothRemoteDevice &device)
601 {
602     HILOGI("enter");
603     if (!IS_BT_ENABLED()) {
604         HILOGE("bluetooth is off.");
605         return RET_BAD_STATUS;
606     }
607 
608     if (pimpl == nullptr || !pimpl->proxy_) {
609         HILOGE("pimpl or a2dpSrc proxy is nullptr");
610         return RET_BAD_STATUS;
611     }
612 
613     if (!device.IsValidBluetoothRemoteDevice()) {
614         HILOGE("input parameter error.");
615         return RET_BAD_PARAM;
616     }
617 
618     return pimpl->proxy_->SuspendPlaying(RawAddress(device.GetDeviceAddr()));
619 }
620 
StopPlaying(const BluetoothRemoteDevice & device)621 int A2dpSource::StopPlaying(const BluetoothRemoteDevice &device)
622 {
623     HILOGI("enter");
624     if (!IS_BT_ENABLED()) {
625         HILOGE("bluetooth is off.");
626         return RET_BAD_STATUS;
627     }
628 
629     if (pimpl == nullptr || !pimpl->proxy_) {
630         HILOGE("pimpl or a2dpSrc proxy is nullptr");
631         return RET_BAD_STATUS;
632     }
633 
634     if (!device.IsValidBluetoothRemoteDevice()) {
635         HILOGE("input parameter error.");
636         return RET_BAD_PARAM;
637     }
638 
639     return pimpl->proxy_->StopPlaying(RawAddress(device.GetDeviceAddr()));
640 }
641 
WriteFrame(const uint8_t * data,uint32_t size)642 int A2dpSource::WriteFrame(const uint8_t *data, uint32_t size)
643 {
644     HILOGI("enter");
645     if (!IS_BT_ENABLED()) {
646         HILOGE("bluetooth is off.");
647         return RET_BAD_STATUS;
648     }
649 
650     if (pimpl == nullptr || !pimpl->proxy_) {
651         HILOGE("pimpl or a2dpSrc proxy is nullptr");
652         return RET_BAD_STATUS;
653     }
654 
655     return pimpl->proxy_->WriteFrame(data, size);
656 }
657 
GetRenderPosition(uint16_t & delayValue,uint16_t & sendDataSize,uint32_t & timeStamp)658 void A2dpSource::GetRenderPosition(uint16_t &delayValue, uint16_t &sendDataSize, uint32_t &timeStamp)
659 {
660     HILOGI("enter");
661     if (!IS_BT_ENABLED()) {
662         HILOGE("bluetooth is off.");
663         return;
664     }
665 
666     if (pimpl == nullptr || !pimpl->proxy_) {
667         HILOGE("pimpl or a2dpSrc proxy is nullptr");
668         return;
669     }
670 
671     pimpl->proxy_->GetRenderPosition(delayValue, sendDataSize, timeStamp);
672 }
673 } // namespace Bluetooth
674 } // namespace OHOS