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_profile_manager.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     BluetoothObserverList<A2dpSourceObserver> observers_;
42     class BluetoothA2dpSourceObserverImp;
43     sptr<BluetoothA2dpSourceObserverImp> observerImp_ = nullptr;
44     int32_t profileRegisterId = 0;
45 };
46 
47 class A2dpSource::impl::BluetoothA2dpSourceObserverImp : public BluetoothA2dpSrcObserverStub {
48 public:
BluetoothA2dpSourceObserverImp(A2dpSource::impl &a2dpSource)49     explicit BluetoothA2dpSourceObserverImp(A2dpSource::impl &a2dpSource) : a2dpSource_(a2dpSource) {};
50     ~BluetoothA2dpSourceObserverImp() override{};
51 
Register(std::shared_ptr<A2dpSourceObserver> &observer)52     void Register(std::shared_ptr<A2dpSourceObserver> &observer)
53     {
54         HILOGI("enter");
55         a2dpSource_.observers_.Register(observer);
56     }
57 
Deregister(std::shared_ptr<A2dpSourceObserver> &observer)58     void Deregister(std::shared_ptr<A2dpSourceObserver> &observer)
59     {
60         HILOGI("enter");
61         a2dpSource_.observers_.Deregister(observer);
62     }
63 
64     void OnConnectionStateChanged(const RawAddress &device, int state, int cause) override
65     {
66         HILOGD("a2dpSrc conn state, device: %{public}s, state: %{public}s, cause: %{public}d",
67             GET_ENCRYPT_RAW_ADDR(device), GetProfileConnStateName(state).c_str(), cause);
68         a2dpSource_.observers_.ForEach([device, state, cause](std::shared_ptr<A2dpSourceObserver> observer) {
69             observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state, cause);
70         });
71     }
72 
73     void OnPlayingStatusChanged(const RawAddress &device, int playingState, int error) override
74     {
75         HILOGI("device: %{public}s, playingState: %{public}d, error: %{public}d",
76             GetEncryptAddr(device.GetAddress()).c_str(), playingState, error);
77         a2dpSource_.observers_.ForEach([device, playingState, error](std::shared_ptr<A2dpSourceObserver> observer) {
78             observer->OnPlayingStatusChanged(BluetoothRemoteDevice(device.GetAddress(), 0), playingState, error);
79         });
80     }
81 
82     void OnConfigurationChanged(const RawAddress &device, const BluetoothA2dpCodecInfo &info, int error) override
83     {
84         HILOGD("device: %{public}s, error: %{public}d", GetEncryptAddr(device.GetAddress()).c_str(), error);
85         a2dpSource_.observers_.ForEach([device, info, error](std::shared_ptr<A2dpSourceObserver> observer) {
86             A2dpCodecInfo codecInfo;
87 
88             codecInfo.bitsPerSample = info.bitsPerSample;
89             codecInfo.channelMode = info.channelMode;
90             codecInfo.codecPriority = info.codecPriority;
91             codecInfo.codecType = info.codecType;
92             codecInfo.sampleRate = info.sampleRate;
93 
94             observer->OnConfigurationChanged(BluetoothRemoteDevice(device.GetAddress(), 0), codecInfo, error);
95         });
96     };
97 
98     void OnMediaStackChanged(const RawAddress &device, int action) override
99     {
100         HILOGI("device: %{public}s, action: %{public}s",
101             GET_ENCRYPT_RAW_ADDR(device), GetUpdateOutputStackActionName(action).c_str());
102         a2dpSource_.observers_.ForEach([device, action](std::shared_ptr<A2dpSourceObserver> observer) {
103             observer->OnMediaStackChanged(BluetoothRemoteDevice(device.GetAddress(), 0), action);
104         });
105     }
106 
107     void OnVirtualDeviceChanged(int action, std::string address) override
108     {
109         HILOGI("device: %{public}s, action: %{public}d", GetEncryptAddr(address).c_str(), action);
110         a2dpSource_.observers_.ForEach([action, address](std::shared_ptr<A2dpSourceObserver> observer) {
111             observer->OnVirtualDeviceChanged(action, address);
112         });
113     }
114 private:
115     A2dpSource::impl &a2dpSource_;
116     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSourceObserverImp);
117 };
118 
impl()119 A2dpSource::impl::impl()
120 {
121     observerImp_ = new (std::nothrow) BluetoothA2dpSourceObserverImp(*this);
122     CHECK_AND_RETURN_LOG(observerImp_ != nullptr, "observerImp_ is nullptr");
123     profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_A2DP_SRC,
124         [this](sptr<IRemoteObject> remote) {
125         sptr<IBluetoothA2dpSrc> proxy = iface_cast<IBluetoothA2dpSrc>(remote);
126         CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
127         proxy->RegisterObserver(observerImp_);
128     });
129 };
130 
~impl()131 A2dpSource::impl::~impl()
132 {
133     HILOGD("start");
134     BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
135     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
136     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
137     proxy->DeregisterObserver(observerImp_);
138 }
139 
A2dpSource()140 A2dpSource::A2dpSource()
141 {
142     pimpl = std::make_unique<impl>();
143     if (!pimpl) {
144         HILOGE("fails: no pimpl");
145     }
146 }
147 
~A2dpSource()148 A2dpSource::~A2dpSource()
149 {
150     HILOGD("start");
151 }
152 
RegisterObserver(std::shared_ptr<A2dpSourceObserver> observer)153 void A2dpSource::RegisterObserver(std::shared_ptr<A2dpSourceObserver> observer)
154 {
155     HILOGD("enter");
156     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
157     pimpl->observers_.Register(observer);
158 }
159 
DeregisterObserver(std::shared_ptr<A2dpSourceObserver> observer)160 void A2dpSource::DeregisterObserver(std::shared_ptr<A2dpSourceObserver> observer)
161 {
162     HILOGD("enter");
163     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
164     pimpl->observers_.Deregister(observer);
165 }
166 
GetDevicesByStates(const std::vector<int> &states, std::vector<BluetoothRemoteDevice> &devices) const167 int A2dpSource::GetDevicesByStates(const std::vector<int> &states, std::vector<BluetoothRemoteDevice> &devices) const
168 {
169     HILOGI("enter");
170     if (!IS_BT_ENABLED()) {
171         HILOGE("bluetooth is off.");
172         return BT_ERR_INVALID_STATE;
173     }
174     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
175     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
176 
177     std::vector<int32_t> convertStates;
178     for (auto state : states) {
179         convertStates.push_back(static_cast<int32_t>(state));
180     }
181 
182     std::vector<RawAddress> rawAddrs;
183     int ret = proxy->GetDevicesByStates(convertStates, rawAddrs);
184     if (ret != BT_NO_ERROR) {
185         HILOGE("GetDevicesByStates return error.");
186         return ret;
187     }
188     for (auto rawAddr : rawAddrs) {
189         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
190         devices.push_back(device);
191     }
192     return BT_NO_ERROR;
193 }
194 
GetDeviceState(const BluetoothRemoteDevice &device, int &state) const195 int A2dpSource::GetDeviceState(const BluetoothRemoteDevice &device, int &state) const
196 {
197     HILOGD("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
198     if (!IS_BT_ENABLED()) {
199         HILOGE("bluetooth is off.");
200         return BT_ERR_INVALID_STATE;
201     }
202     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
203     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
204 
205     if (!device.IsValidBluetoothRemoteDevice()) {
206         HILOGE("input parameter error.");
207         return BT_ERR_INVALID_PARAM;
208     }
209 
210     int ret = proxy->GetDeviceState(RawAddress(device.GetDeviceAddr()), state);
211     HILOGD("state: %{public}d", ret);
212     return ret;
213 }
214 
GetPlayingState(const BluetoothRemoteDevice &device) const215 int32_t A2dpSource::GetPlayingState(const BluetoothRemoteDevice &device) const
216 {
217     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
218     if (!IS_BT_ENABLED()) {
219         HILOGE("bluetooth is off.");
220         return RET_BAD_STATUS;
221     }
222     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
223     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
224 
225     if (!device.IsValidBluetoothRemoteDevice()) {
226         HILOGE("input parameter error.");
227         return RET_BAD_PARAM;
228     }
229 
230     int ret = RET_NO_ERROR;
231     proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
232     HILOGI("state: %{public}d", ret);
233     return ret;
234 }
235 
GetPlayingState(const BluetoothRemoteDevice &device, int &state) const236 int32_t A2dpSource::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
237 {
238     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
239     if (!IS_BT_ENABLED()) {
240         HILOGE("bluetooth is off.");
241         return BT_ERR_INVALID_STATE;
242     }
243     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
244     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
245 
246     if (!device.IsValidBluetoothRemoteDevice()) {
247         HILOGE("input parameter error.");
248         return BT_ERR_INVALID_PARAM;
249     }
250 
251     return proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
252 }
253 
Connect(const BluetoothRemoteDevice &device)254 int32_t A2dpSource::Connect(const BluetoothRemoteDevice &device)
255 {
256     HILOGI("a2dp connect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
257     if (!IS_BT_ENABLED()) {
258         HILOGE("bluetooth is off.");
259         return BT_ERR_INVALID_STATE;
260     }
261 
262     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
263     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
264 
265     if (!device.IsValidBluetoothRemoteDevice()) {
266         HILOGE("input parameter error.");
267         return BT_ERR_INVALID_PARAM;
268     }
269     return proxy->Connect(RawAddress(device.GetDeviceAddr()));
270 }
271 
Disconnect(const BluetoothRemoteDevice &device)272 int32_t A2dpSource::Disconnect(const BluetoothRemoteDevice &device)
273 {
274     HILOGI("a2dp disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
275     if (!IS_BT_ENABLED()) {
276         HILOGE("bluetooth is off.");
277         return BT_ERR_INVALID_STATE;
278     }
279 
280     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
281     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
282 
283     if (!device.IsValidBluetoothRemoteDevice()) {
284         HILOGE("input parameter error.");
285         return BT_ERR_INVALID_PARAM;
286     }
287 
288     return proxy->Disconnect(RawAddress(device.GetDeviceAddr()));
289 }
290 
GetProfile()291 A2dpSource *A2dpSource::GetProfile()
292 {
293     HILOGD("enter");
294 #ifdef DTFUZZ_TEST
295     static BluetoothNoDestructor<A2dpSource> service;
296     return service.get();
297 #else
298     static A2dpSource service;
299     return &service;
300 #endif
301 }
302 
SetActiveSinkDevice(const BluetoothRemoteDevice &device)303 int A2dpSource::SetActiveSinkDevice(const BluetoothRemoteDevice &device)
304 {
305     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
306     if (!IS_BT_ENABLED()) {
307         HILOGE("bluetooth is off.");
308         return RET_BAD_STATUS;
309     }
310     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
311     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
312 
313     if (!device.IsValidBluetoothRemoteDevice()) {
314         HILOGE("input parameter error.");
315         return RET_BAD_PARAM;
316     }
317 
318     return proxy->SetActiveSinkDevice(RawAddress(device.GetDeviceAddr()));
319 }
320 
GetActiveSinkDevice() const321 const BluetoothRemoteDevice &A2dpSource::GetActiveSinkDevice() const
322 {
323     HILOGI("enter");
324     static BluetoothRemoteDevice deviceInfo;
325     if (!IS_BT_ENABLED()) {
326         HILOGE("bluetooth is off.");
327         return deviceInfo;
328     }
329     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
330     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, deviceInfo, "failed: no proxy");
331 
332     BluetoothRawAddress rawAddress = proxy->GetActiveSinkDevice();
333     deviceInfo = BluetoothRemoteDevice(rawAddress.GetAddress(), 0);
334     return deviceInfo;
335 }
336 
SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)337 int A2dpSource::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
338 {
339     HILOGI("device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
340     if (!IS_BT_ENABLED()) {
341         HILOGE("bluetooth is off.");
342         return BT_ERR_INVALID_STATE;
343     }
344     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
345     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
346 
347     if ((!device.IsValidBluetoothRemoteDevice()) || (
348         (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
349         (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
350         HILOGI("input parameter error.");
351         return BT_ERR_INVALID_PARAM;
352     }
353 
354     return proxy->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
355 }
356 
GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const357 int A2dpSource::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
358 {
359     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
360     if (!IS_BT_ENABLED()) {
361         HILOGE("bluetooth is off.");
362         return BT_ERR_INVALID_STATE;
363     }
364     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
365     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "failed: no proxy");
366 
367     if (!device.IsValidBluetoothRemoteDevice()) {
368         HILOGI("input parameter error.");
369         return BT_ERR_INVALID_PARAM;
370     }
371 
372     return proxy->GetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
373 }
374 
GetCodecStatus(const BluetoothRemoteDevice &device) const375 A2dpCodecStatus A2dpSource::GetCodecStatus(const BluetoothRemoteDevice &device) const
376 {
377     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
378     A2dpCodecStatus ret;
379     if (!IS_BT_ENABLED()) {
380         HILOGE("bluetooth is off.");
381         return ret;
382     }
383     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
384     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, ret, "failed: no proxy");
385 
386     if (!device.IsValidBluetoothRemoteDevice()) {
387         HILOGE("input parameter error.");
388         return ret;
389     }
390 
391     BluetoothA2dpCodecStatus codecStatus = proxy->GetCodecStatus(RawAddress(device.GetDeviceAddr()));
392     ret.codecInfo.codecType = codecStatus.codecInfo.codecType;
393     ret.codecInfo.sampleRate = codecStatus.codecInfo.sampleRate;
394     ret.codecInfo.channelMode = codecStatus.codecInfo.channelMode;
395     ret.codecInfo.codecPriority = codecStatus.codecInfo.codecPriority;
396     ret.codecInfo.bitsPerSample = codecStatus.codecInfo.bitsPerSample;
397 
398     A2dpCodecInfo serviceInfo;
399     for (auto it = codecStatus.codecInfoConfirmCap.begin(); it != codecStatus.codecInfoConfirmCap.end(); it++) {
400         serviceInfo.codecType = it->codecType;
401         serviceInfo.sampleRate = it->sampleRate;
402         serviceInfo.channelMode = it->channelMode;
403         serviceInfo.codecPriority = it->codecPriority;
404         serviceInfo.bitsPerSample = it->bitsPerSample;
405         ret.codecInfoConfirmedCap.push_back(serviceInfo);
406     }
407 
408     for (auto it = codecStatus.codecInfoLocalCap.begin(); it != codecStatus.codecInfoLocalCap.end(); it++) {
409         serviceInfo.codecType = it->codecType;
410         serviceInfo.sampleRate = it->sampleRate;
411         serviceInfo.channelMode = it->channelMode;
412         serviceInfo.codecPriority = it->codecPriority;
413         serviceInfo.bitsPerSample = it->bitsPerSample;
414         ret.codecInfoLocalCap.push_back(serviceInfo);
415     }
416     return ret;
417 }
418 
GetCodecPreference(const BluetoothRemoteDevice &device, A2dpCodecInfo &info)419 int A2dpSource::GetCodecPreference(const BluetoothRemoteDevice &device, A2dpCodecInfo &info)
420 {
421     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
422     if (!IS_BT_ENABLED()) {
423         HILOGE("bluetooth is off.");
424         return BT_ERR_INVALID_STATE;
425     }
426     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
427     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
428 
429     if (!device.IsValidBluetoothRemoteDevice()) {
430         HILOGE("input parameter error.");
431         return BT_ERR_INVALID_PARAM;
432     }
433 
434     BluetoothA2dpCodecInfo serviceInfo;
435     int ret = proxy->GetCodecPreference(RawAddress(device.GetDeviceAddr()), serviceInfo);
436     if (ret != BT_NO_ERROR) {
437         HILOGE("GetCodecPreference error.");
438         return ret;
439     }
440     info.codecType = serviceInfo.codecType;
441     info.sampleRate = serviceInfo.sampleRate;
442     info.channelMode = serviceInfo.channelMode;
443     info.bitsPerSample = serviceInfo.bitsPerSample;
444     return ret;
445 }
446 
SetCodecPreference(const BluetoothRemoteDevice &device, const A2dpCodecInfo &info)447 int A2dpSource::SetCodecPreference(const BluetoothRemoteDevice &device, const A2dpCodecInfo &info)
448 {
449     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
450     if (!IS_BT_ENABLED()) {
451         HILOGE("bluetooth is off.");
452         return BT_ERR_INVALID_STATE;
453     }
454     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
455     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
456 
457     if (!device.IsValidBluetoothRemoteDevice()) {
458         HILOGE("input parameter error.");
459         return BT_ERR_INVALID_PARAM;
460     }
461 
462     BluetoothA2dpCodecInfo serviceInfo;
463     serviceInfo.codecType = info.codecType;
464     serviceInfo.sampleRate = info.sampleRate;
465     serviceInfo.channelMode = info.channelMode;
466     serviceInfo.bitsPerSample = info.bitsPerSample;
467     serviceInfo.codecPriority = info.codecPriority;
468     serviceInfo.codecSpecific1 = info.codecSpecific1;
469     serviceInfo.codecSpecific2 = info.codecSpecific2;
470     serviceInfo.codecSpecific3 = info.codecSpecific3;
471     serviceInfo.codecSpecific4 = info.codecSpecific4;
472 
473     return proxy->SetCodecPreference(RawAddress(device.GetDeviceAddr()), serviceInfo);
474 }
475 
SwitchOptionalCodecs(const BluetoothRemoteDevice &device, bool isEnable)476 void A2dpSource::SwitchOptionalCodecs(const BluetoothRemoteDevice &device, bool isEnable)
477 {
478     HILOGI("enter");
479     if (!IS_BT_ENABLED()) {
480         HILOGE("bluetooth is off.");
481         return;
482     }
483     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
484     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
485 
486     if (!device.IsValidBluetoothRemoteDevice()) {
487         HILOGE("input parameter error.");
488         return;
489     }
490 
491     proxy->SwitchOptionalCodecs(RawAddress(device.GetDeviceAddr()), isEnable);
492 }
493 
GetOptionalCodecsSupportState(const BluetoothRemoteDevice &device) const494 int A2dpSource::GetOptionalCodecsSupportState(const BluetoothRemoteDevice &device) const
495 {
496     HILOGI("enter");
497     if (!IS_BT_ENABLED()) {
498         HILOGE("bluetooth is off.");
499         return RET_BAD_STATUS;
500     }
501     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
502     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
503 
504     if (!device.IsValidBluetoothRemoteDevice()) {
505         HILOGE("input parameter error.");
506         return RET_BAD_PARAM;
507     }
508 
509     return proxy->GetOptionalCodecsSupportState(RawAddress(device.GetDeviceAddr()));
510 }
511 
StartPlaying(const BluetoothRemoteDevice &device)512 int A2dpSource::StartPlaying(const BluetoothRemoteDevice &device)
513 {
514     HILOGI("enter");
515     if (!IS_BT_ENABLED()) {
516         HILOGE("bluetooth is off.");
517         return RET_BAD_STATUS;
518     }
519 
520     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
521     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
522 
523     if (!device.IsValidBluetoothRemoteDevice()) {
524         HILOGE("input parameter error.");
525         return RET_BAD_PARAM;
526     }
527 
528     return proxy->StartPlaying(RawAddress(device.GetDeviceAddr()));
529 }
530 
SuspendPlaying(const BluetoothRemoteDevice &device)531 int A2dpSource::SuspendPlaying(const BluetoothRemoteDevice &device)
532 {
533     HILOGI("enter");
534     if (!IS_BT_ENABLED()) {
535         HILOGE("bluetooth is off.");
536         return RET_BAD_STATUS;
537     }
538 
539     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
540     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
541 
542     if (!device.IsValidBluetoothRemoteDevice()) {
543         HILOGE("input parameter error.");
544         return RET_BAD_PARAM;
545     }
546 
547     return proxy->SuspendPlaying(RawAddress(device.GetDeviceAddr()));
548 }
549 
StopPlaying(const BluetoothRemoteDevice &device)550 int A2dpSource::StopPlaying(const BluetoothRemoteDevice &device)
551 {
552     HILOGI("enter");
553     if (!IS_BT_ENABLED()) {
554         HILOGE("bluetooth is off.");
555         return RET_BAD_STATUS;
556     }
557 
558     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
559     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
560 
561     if (!device.IsValidBluetoothRemoteDevice()) {
562         HILOGE("input parameter error.");
563         return RET_BAD_PARAM;
564     }
565 
566     return proxy->StopPlaying(RawAddress(device.GetDeviceAddr()));
567 }
568 
WriteFrame(const uint8_t *data, uint32_t size)569 int A2dpSource::WriteFrame(const uint8_t *data, uint32_t size)
570 {
571     HILOGI("enter");
572     if (!IS_BT_ENABLED()) {
573         HILOGE("bluetooth is off.");
574         return RET_BAD_STATUS;
575     }
576 
577     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
578     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
579 
580     return proxy->WriteFrame(data, size);
581 }
582 
GetRenderPosition(const BluetoothRemoteDevice &device, uint32_t &delayValue, uint64_t &sendDataSize, uint32_t &timeStamp)583 int A2dpSource::GetRenderPosition(const BluetoothRemoteDevice &device, uint32_t &delayValue, uint64_t &sendDataSize,
584                                   uint32_t &timeStamp)
585 {
586     HILOGI("enter");
587     if (!IS_BT_ENABLED()) {
588         HILOGE("bluetooth is off.");
589         return RET_BAD_STATUS;
590     }
591     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device err");
592     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
593     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "a2dpSrc proxy is nullptr");
594     return proxy->GetRenderPosition(RawAddress(device.GetDeviceAddr()), delayValue, sendDataSize, timeStamp);
595 }
596 
OffloadStartPlaying(const BluetoothRemoteDevice &device, const std::vector<int32_t> &sessionsId)597 int A2dpSource::OffloadStartPlaying(const BluetoothRemoteDevice &device, const std::vector<int32_t> &sessionsId)
598 {
599     HILOGI("enter, start playing device:%{public}s", GET_ENCRYPT_ADDR(device));
600     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device err");
601     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, BT_ERR_INVALID_PARAM, "invaild mac");
602     CHECK_AND_RETURN_LOG_RET(sessionsId.size() != 0, BT_ERR_INVALID_PARAM, "session size zero.");
603     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
604     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
605     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY,
606         "a2dpSrc proxy is nullptr");
607     return proxy->OffloadStartPlaying(RawAddress(device.GetDeviceAddr()), sessionsId);
608 }
609 
OffloadStopPlaying(const BluetoothRemoteDevice &device, const std::vector<int32_t> &sessionsId)610 int A2dpSource::OffloadStopPlaying(const BluetoothRemoteDevice &device, const std::vector<int32_t> &sessionsId)
611 {
612     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device err");
613     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, BT_ERR_INVALID_PARAM, "invaild mac");
614     CHECK_AND_RETURN_LOG_RET(sessionsId.size() != 0, BT_ERR_INVALID_PARAM, "session size zero.");
615     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
616     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
617     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY,
618         "a2dpSrc proxy is nullptr");
619     return proxy->OffloadStopPlaying(RawAddress(device.GetDeviceAddr()), sessionsId);
620 }
621 
A2dpOffloadSessionRequest(const BluetoothRemoteDevice &device, const std::vector<A2dpStreamInfo> &info)622 int A2dpSource::A2dpOffloadSessionRequest(const BluetoothRemoteDevice &device, const std::vector<A2dpStreamInfo> &info)
623 {
624     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), A2DP_STREAM_ENCODE_UNKNOWN, "device err");
625     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, A2DP_STREAM_ENCODE_UNKNOWN, "invaild mac");
626     CHECK_AND_RETURN_LOG_RET(info.size() != 0, A2DP_STREAM_ENCODE_SOFTWARE, "empty stream");
627     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), A2DP_STREAM_ENCODE_UNKNOWN, "bluetooth is off.");
628     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
629     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, A2DP_STREAM_ENCODE_UNKNOWN, "a2dpSrc proxy is nullptr");
630 
631     std::vector<BluetoothA2dpStreamInfo> streamsInfo = {};
632     BluetoothA2dpStreamInfo streamInfo;
633     for (auto stream : info) {
634         streamInfo.sessionId = stream.sessionId;
635         streamInfo.streamType = stream.streamType;
636         streamInfo.sampleRate = stream.sampleRate;
637         streamInfo.isSpatialAudio = stream.isSpatialAudio;
638         streamsInfo.push_back(streamInfo);
639     }
640     return proxy->A2dpOffloadSessionPathRequest(RawAddress(device.GetDeviceAddr()), streamsInfo);
641 }
642 
A2dpOffloadCodecStatus(const BluetoothA2dpOffloadCodecStatus &status)643 A2dpOffloadCodecStatus::A2dpOffloadCodecStatus(const BluetoothA2dpOffloadCodecStatus &status)
644 {
645     offloadInfo.mediaPacketHeader = status.offloadInfo.mediaPacketHeader;
646     offloadInfo.mPt = status.offloadInfo.mPt;
647     offloadInfo.ssrc = status.offloadInfo.ssrc;
648     offloadInfo.boundaryFlag = status.offloadInfo.boundaryFlag;
649     offloadInfo.broadcastFlag = status.offloadInfo.broadcastFlag;
650     offloadInfo.codecType = status.offloadInfo.codecType;
651     offloadInfo.maxLatency = status.offloadInfo.maxLatency;
652     offloadInfo.scmsTEnable = status.offloadInfo.scmsTEnable;
653     offloadInfo.sampleRate = status.offloadInfo.sampleRate;
654     offloadInfo.encodedAudioBitrate = status.offloadInfo.encodedAudioBitrate;
655     offloadInfo.bitsPerSample = status.offloadInfo.bitsPerSample;
656     offloadInfo.chMode = status.offloadInfo.chMode;
657     offloadInfo.aclHdl = status.offloadInfo.aclHdl;
658     offloadInfo.l2cRcid = status.offloadInfo.l2cRcid;
659     offloadInfo.mtu = status.offloadInfo.mtu;
660     offloadInfo.codecSpecific0 = status.offloadInfo.codecSpecific0;
661     offloadInfo.codecSpecific1 = status.offloadInfo.codecSpecific1;
662     offloadInfo.codecSpecific2 = status.offloadInfo.codecSpecific2;
663     offloadInfo.codecSpecific3 = status.offloadInfo.codecSpecific3;
664     offloadInfo.codecSpecific4 = status.offloadInfo.codecSpecific4;
665     offloadInfo.codecSpecific5 = status.offloadInfo.codecSpecific5;
666     offloadInfo.codecSpecific6 = status.offloadInfo.codecSpecific6;
667     offloadInfo.codecSpecific7 = status.offloadInfo.codecSpecific7;
668 }
669 
GetOffloadCodecStatus(const BluetoothRemoteDevice &device) const670 A2dpOffloadCodecStatus A2dpSource::GetOffloadCodecStatus(const BluetoothRemoteDevice &device) const
671 {
672     HILOGI("enter");
673     A2dpOffloadCodecStatus ret;
674     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), ret, "input device err");
675     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, ret, "invaild mac");
676     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), ret, "bluetooth is off.");
677     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
678     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, ret, "a2dpSrc proxy is nullptr");
679     BluetoothA2dpOffloadCodecStatus offloadStatus(proxy->GetOffloadCodecStatus(RawAddress(device.GetDeviceAddr())));
680     A2dpOffloadCodecStatus status(offloadStatus);
681     HILOGI("codecType:%{public}x,mtu:%{public}d", status.offloadInfo.codecType, status.offloadInfo.mtu);
682     return status;
683 }
684 
EnableAutoPlay(const BluetoothRemoteDevice &device)685 int A2dpSource::EnableAutoPlay(const BluetoothRemoteDevice &device)
686 {
687     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "input device err");
688     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
689     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
690     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "a2dpSrc proxy is nullptr");
691     return proxy->EnableAutoPlay(RawAddress(device.GetDeviceAddr()));
692 }
693 
DisableAutoPlay(const BluetoothRemoteDevice &device, const int duration)694 int A2dpSource::DisableAutoPlay(const BluetoothRemoteDevice &device, const int duration)
695 {
696     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "input device err");
697     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
698     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
699     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "a2dpSrc proxy is nullptr");
700     return proxy->DisableAutoPlay(RawAddress(device.GetDeviceAddr()), duration);
701 }
702 
GetAutoPlayDisabledDuration(const BluetoothRemoteDevice &device, int &duration)703 int A2dpSource::GetAutoPlayDisabledDuration(const BluetoothRemoteDevice &device, int &duration)
704 {
705     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "input device err");
706     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
707     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
708     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "a2dpSrc proxy is nullptr");
709     return proxy->GetAutoPlayDisabledDuration(RawAddress(device.GetDeviceAddr()), duration);
710 }
711 
GetVirtualDeviceList(std::vector<std::string> &devices)712 void A2dpSource::GetVirtualDeviceList(std::vector<std::string> &devices)
713 {
714     CHECK_AND_RETURN_LOG(IS_BT_ENABLED(), "bluetooth is off.");
715     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
716     CHECK_AND_RETURN_LOG(proxy != nullptr, "a2dpSrc proxy is nullptr");
717     proxy->GetVirtualDeviceList(devices);
718 }
719 } // namespace Bluetooth
720 } // namespace OHOS