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