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