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