• 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     pimpl->observers_.Register(observer);
175 }
176 
DeregisterObserver(std::shared_ptr<A2dpSourceObserver> observer)177 void A2dpSource::DeregisterObserver(std::shared_ptr<A2dpSourceObserver> observer)
178 {
179     HILOGD("enter");
180     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
181     pimpl->observers_.Deregister(observer);
182 }
183 
GetDevicesByStates(const std::vector<int> & states,std::vector<BluetoothRemoteDevice> & devices) const184 int A2dpSource::GetDevicesByStates(const std::vector<int> &states, std::vector<BluetoothRemoteDevice> &devices) const
185 {
186     HILOGI("enter");
187     if (!IS_BT_ENABLED()) {
188         HILOGE("bluetooth is off.");
189         return BT_ERR_INVALID_STATE;
190     }
191     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
192     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
193 
194     std::vector<int32_t> convertStates;
195     for (auto state : states) {
196         convertStates.push_back(static_cast<int32_t>(state));
197     }
198 
199     std::vector<RawAddress> rawAddrs;
200     int ret = proxy->GetDevicesByStates(convertStates, rawAddrs);
201     if (ret != BT_NO_ERROR) {
202         HILOGE("GetDevicesByStates return error.");
203         return ret;
204     }
205     for (auto rawAddr : rawAddrs) {
206         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
207         devices.push_back(device);
208     }
209     return BT_NO_ERROR;
210 }
211 
GetDeviceState(const BluetoothRemoteDevice & device,int & state) const212 int A2dpSource::GetDeviceState(const BluetoothRemoteDevice &device, int &state) const
213 {
214     HILOGD("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
215     if (!IS_BT_ENABLED()) {
216         HILOGE("bluetooth is off.");
217         return BT_ERR_INVALID_STATE;
218     }
219     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
220     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
221 
222     if (!device.IsValidBluetoothRemoteDevice()) {
223         HILOGE("input parameter error.");
224         return BT_ERR_INVALID_PARAM;
225     }
226 
227     int ret = proxy->GetDeviceState(RawAddress(device.GetDeviceAddr()), state);
228     HILOGD("state: %{public}d", ret);
229     return ret;
230 }
231 
GetPlayingState(const BluetoothRemoteDevice & device) const232 int32_t A2dpSource::GetPlayingState(const BluetoothRemoteDevice &device) const
233 {
234     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
235     if (!IS_BT_ENABLED()) {
236         HILOGE("bluetooth is off.");
237         return RET_BAD_STATUS;
238     }
239     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
240     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
241 
242     if (!device.IsValidBluetoothRemoteDevice()) {
243         HILOGE("input parameter error.");
244         return RET_BAD_PARAM;
245     }
246 
247     int ret = RET_NO_ERROR;
248     proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret);
249     HILOGI("state: %{public}d", ret);
250     return ret;
251 }
252 
GetPlayingState(const BluetoothRemoteDevice & device,int & state) const253 int32_t A2dpSource::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const
254 {
255     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
256     if (!IS_BT_ENABLED()) {
257         HILOGE("bluetooth is off.");
258         return BT_ERR_INVALID_STATE;
259     }
260     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
261     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
262 
263     if (!device.IsValidBluetoothRemoteDevice()) {
264         HILOGE("input parameter error.");
265         return BT_ERR_INVALID_PARAM;
266     }
267 
268     return proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), state);
269 }
270 
Connect(const BluetoothRemoteDevice & device)271 int32_t A2dpSource::Connect(const BluetoothRemoteDevice &device)
272 {
273     HILOGI("a2dp connect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
274     if (!IS_BT_ENABLED()) {
275         HILOGE("bluetooth is off.");
276         return BT_ERR_INVALID_STATE;
277     }
278 
279     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
280     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
281 
282     if (!device.IsValidBluetoothRemoteDevice()) {
283         HILOGE("input parameter error.");
284         return BT_ERR_INVALID_PARAM;
285     }
286     return proxy->Connect(RawAddress(device.GetDeviceAddr()));
287 }
288 
Disconnect(const BluetoothRemoteDevice & device)289 int32_t A2dpSource::Disconnect(const BluetoothRemoteDevice &device)
290 {
291     HILOGI("a2dp disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
292     if (!IS_BT_ENABLED()) {
293         HILOGE("bluetooth is off.");
294         return BT_ERR_INVALID_STATE;
295     }
296 
297     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
298     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
299 
300     if (!device.IsValidBluetoothRemoteDevice()) {
301         HILOGE("input parameter error.");
302         return BT_ERR_INVALID_PARAM;
303     }
304 
305     return proxy->Disconnect(RawAddress(device.GetDeviceAddr()));
306 }
307 
GetProfile()308 A2dpSource *A2dpSource::GetProfile()
309 {
310     HILOGD("enter");
311 #ifdef DTFUZZ_TEST
312     static BluetoothNoDestructor<A2dpSource> service;
313     return service.get();
314 #else
315     static A2dpSource service;
316     return &service;
317 #endif
318 }
319 
SetActiveSinkDevice(const BluetoothRemoteDevice & device)320 int A2dpSource::SetActiveSinkDevice(const BluetoothRemoteDevice &device)
321 {
322     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
323     if (!IS_BT_ENABLED()) {
324         HILOGE("bluetooth is off.");
325         return RET_BAD_STATUS;
326     }
327     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
328     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
329 
330     if (!device.IsValidBluetoothRemoteDevice()) {
331         HILOGE("input parameter error.");
332         return RET_BAD_PARAM;
333     }
334 
335     return proxy->SetActiveSinkDevice(RawAddress(device.GetDeviceAddr()));
336 }
337 
GetActiveSinkDevice() const338 const BluetoothRemoteDevice &A2dpSource::GetActiveSinkDevice() const
339 {
340     HILOGI("enter");
341     static BluetoothRemoteDevice deviceInfo;
342     if (!IS_BT_ENABLED()) {
343         HILOGE("bluetooth is off.");
344         return deviceInfo;
345     }
346     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
347     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, deviceInfo, "failed: no proxy");
348 
349     BluetoothRawAddress rawAddress = proxy->GetActiveSinkDevice();
350     deviceInfo = BluetoothRemoteDevice(rawAddress.GetAddress(), 0);
351     return deviceInfo;
352 }
353 
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)354 int A2dpSource::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
355 {
356     HILOGI("device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
357     if (!IS_BT_ENABLED()) {
358         HILOGE("bluetooth is off.");
359         return BT_ERR_INVALID_STATE;
360     }
361     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
362     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
363 
364     if ((!device.IsValidBluetoothRemoteDevice()) || (
365         (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
366         (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
367         HILOGI("input parameter error.");
368         return BT_ERR_INVALID_PARAM;
369     }
370 
371     return proxy->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
372 }
373 
GetConnectStrategy(const BluetoothRemoteDevice & device,int & strategy) const374 int A2dpSource::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
375 {
376     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
377     if (!IS_BT_ENABLED()) {
378         HILOGE("bluetooth is off.");
379         return BT_ERR_INVALID_STATE;
380     }
381     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
382     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "failed: no proxy");
383 
384     if (!device.IsValidBluetoothRemoteDevice()) {
385         HILOGI("input parameter error.");
386         return BT_ERR_INVALID_PARAM;
387     }
388 
389     return proxy->GetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy);
390 }
391 
GetCodecStatus(const BluetoothRemoteDevice & device) const392 A2dpCodecStatus A2dpSource::GetCodecStatus(const BluetoothRemoteDevice &device) const
393 {
394     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
395     A2dpCodecStatus ret;
396     if (!IS_BT_ENABLED()) {
397         HILOGE("bluetooth is off.");
398         return ret;
399     }
400     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
401     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, ret, "failed: no proxy");
402 
403     if (!device.IsValidBluetoothRemoteDevice()) {
404         HILOGE("input parameter error.");
405         return ret;
406     }
407 
408     BluetoothA2dpCodecStatus codecStatus = proxy->GetCodecStatus(RawAddress(device.GetDeviceAddr()));
409     ret.codecInfo.codecType = codecStatus.codecInfo.codecType;
410     ret.codecInfo.sampleRate = codecStatus.codecInfo.sampleRate;
411     ret.codecInfo.channelMode = codecStatus.codecInfo.channelMode;
412     ret.codecInfo.codecPriority = codecStatus.codecInfo.codecPriority;
413     ret.codecInfo.bitsPerSample = codecStatus.codecInfo.bitsPerSample;
414 
415     A2dpCodecInfo serviceInfo;
416     for (auto it = codecStatus.codecInfoConfirmCap.begin(); it != codecStatus.codecInfoConfirmCap.end(); it++) {
417         serviceInfo.codecType = it->codecType;
418         serviceInfo.sampleRate = it->sampleRate;
419         serviceInfo.channelMode = it->channelMode;
420         serviceInfo.codecPriority = it->codecPriority;
421         serviceInfo.bitsPerSample = it->bitsPerSample;
422         ret.codecInfoConfirmedCap.push_back(serviceInfo);
423     }
424 
425     for (auto it = codecStatus.codecInfoLocalCap.begin(); it != codecStatus.codecInfoLocalCap.end(); it++) {
426         serviceInfo.codecType = it->codecType;
427         serviceInfo.sampleRate = it->sampleRate;
428         serviceInfo.channelMode = it->channelMode;
429         serviceInfo.codecPriority = it->codecPriority;
430         serviceInfo.bitsPerSample = it->bitsPerSample;
431         ret.codecInfoLocalCap.push_back(serviceInfo);
432     }
433     return ret;
434 }
435 
GetCodecPreference(const BluetoothRemoteDevice & device,A2dpCodecInfo & info)436 int A2dpSource::GetCodecPreference(const BluetoothRemoteDevice &device, A2dpCodecInfo &info)
437 {
438     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
439     if (!IS_BT_ENABLED()) {
440         HILOGE("bluetooth is off.");
441         return BT_ERR_INVALID_STATE;
442     }
443     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
444     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
445 
446     if (!device.IsValidBluetoothRemoteDevice()) {
447         HILOGE("input parameter error.");
448         return BT_ERR_INVALID_PARAM;
449     }
450 
451     BluetoothA2dpCodecInfo serviceInfo;
452     int ret = proxy->GetCodecPreference(RawAddress(device.GetDeviceAddr()), serviceInfo);
453     if (ret != BT_NO_ERROR) {
454         HILOGE("GetCodecPreference error.");
455         return ret;
456     }
457     info.codecType = serviceInfo.codecType;
458     info.sampleRate = serviceInfo.sampleRate;
459     info.channelMode = serviceInfo.channelMode;
460     info.bitsPerSample = serviceInfo.bitsPerSample;
461     return ret;
462 }
463 
SetCodecPreference(const BluetoothRemoteDevice & device,const A2dpCodecInfo & info)464 int A2dpSource::SetCodecPreference(const BluetoothRemoteDevice &device, const A2dpCodecInfo &info)
465 {
466     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
467     if (!IS_BT_ENABLED()) {
468         HILOGE("bluetooth is off.");
469         return BT_ERR_INVALID_STATE;
470     }
471     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
472     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
473 
474     if (!device.IsValidBluetoothRemoteDevice()) {
475         HILOGE("input parameter error.");
476         return BT_ERR_INVALID_PARAM;
477     }
478 
479     BluetoothA2dpCodecInfo serviceInfo;
480     serviceInfo.codecType = info.codecType;
481     serviceInfo.sampleRate = info.sampleRate;
482     serviceInfo.channelMode = info.channelMode;
483     serviceInfo.bitsPerSample = info.bitsPerSample;
484     serviceInfo.codecPriority = info.codecPriority;
485     serviceInfo.codecSpecific1 = info.codecSpecific1;
486     serviceInfo.codecSpecific2 = info.codecSpecific2;
487     serviceInfo.codecSpecific3 = info.codecSpecific3;
488     serviceInfo.codecSpecific4 = info.codecSpecific4;
489 
490     return proxy->SetCodecPreference(RawAddress(device.GetDeviceAddr()), serviceInfo);
491 }
492 
SwitchOptionalCodecs(const BluetoothRemoteDevice & device,bool isEnable)493 void A2dpSource::SwitchOptionalCodecs(const BluetoothRemoteDevice &device, bool isEnable)
494 {
495     HILOGI("enter");
496     if (!IS_BT_ENABLED()) {
497         HILOGE("bluetooth is off.");
498         return;
499     }
500     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
501     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
502 
503     if (!device.IsValidBluetoothRemoteDevice()) {
504         HILOGE("input parameter error.");
505         return;
506     }
507 
508     proxy->SwitchOptionalCodecs(RawAddress(device.GetDeviceAddr()), isEnable);
509 }
510 
GetOptionalCodecsSupportState(const BluetoothRemoteDevice & device) const511 int A2dpSource::GetOptionalCodecsSupportState(const BluetoothRemoteDevice &device) const
512 {
513     HILOGI("enter");
514     if (!IS_BT_ENABLED()) {
515         HILOGE("bluetooth is off.");
516         return RET_BAD_STATUS;
517     }
518     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
519     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
520 
521     if (!device.IsValidBluetoothRemoteDevice()) {
522         HILOGE("input parameter error.");
523         return RET_BAD_PARAM;
524     }
525 
526     return proxy->GetOptionalCodecsSupportState(RawAddress(device.GetDeviceAddr()));
527 }
528 
StartPlaying(const BluetoothRemoteDevice & device)529 int A2dpSource::StartPlaying(const BluetoothRemoteDevice &device)
530 {
531     HILOGI("enter");
532     if (!IS_BT_ENABLED()) {
533         HILOGE("bluetooth is off.");
534         return RET_BAD_STATUS;
535     }
536 
537     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
538     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
539 
540     if (!device.IsValidBluetoothRemoteDevice()) {
541         HILOGE("input parameter error.");
542         return RET_BAD_PARAM;
543     }
544 
545     return proxy->StartPlaying(RawAddress(device.GetDeviceAddr()));
546 }
547 
SuspendPlaying(const BluetoothRemoteDevice & device)548 int A2dpSource::SuspendPlaying(const BluetoothRemoteDevice &device)
549 {
550     HILOGI("enter");
551     if (!IS_BT_ENABLED()) {
552         HILOGE("bluetooth is off.");
553         return RET_BAD_STATUS;
554     }
555 
556     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
557     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
558 
559     if (!device.IsValidBluetoothRemoteDevice()) {
560         HILOGE("input parameter error.");
561         return RET_BAD_PARAM;
562     }
563 
564     return proxy->SuspendPlaying(RawAddress(device.GetDeviceAddr()));
565 }
566 
StopPlaying(const BluetoothRemoteDevice & device)567 int A2dpSource::StopPlaying(const BluetoothRemoteDevice &device)
568 {
569     HILOGI("enter");
570     if (!IS_BT_ENABLED()) {
571         HILOGE("bluetooth is off.");
572         return RET_BAD_STATUS;
573     }
574 
575     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
576     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
577 
578     if (!device.IsValidBluetoothRemoteDevice()) {
579         HILOGE("input parameter error.");
580         return RET_BAD_PARAM;
581     }
582 
583     return proxy->StopPlaying(RawAddress(device.GetDeviceAddr()));
584 }
585 
WriteFrame(const uint8_t * data,uint32_t size)586 int A2dpSource::WriteFrame(const uint8_t *data, uint32_t size)
587 {
588     HILOGI("enter");
589     if (!IS_BT_ENABLED()) {
590         HILOGE("bluetooth is off.");
591         return RET_BAD_STATUS;
592     }
593 
594     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
595     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "failed: no proxy");
596 
597     return proxy->WriteFrame(data, size);
598 }
599 
GetRenderPosition(const BluetoothRemoteDevice & device,uint32_t & delayValue,uint64_t & sendDataSize,uint32_t & timeStamp)600 int A2dpSource::GetRenderPosition(const BluetoothRemoteDevice &device, uint32_t &delayValue, uint64_t &sendDataSize,
601                                   uint32_t &timeStamp)
602 {
603     HILOGI("enter");
604     if (!IS_BT_ENABLED()) {
605         HILOGE("bluetooth is off.");
606         return RET_BAD_STATUS;
607     }
608     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device err");
609     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
610     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
611     return proxy->GetRenderPosition(RawAddress(device.GetDeviceAddr()), delayValue, sendDataSize, timeStamp);
612 }
613 
OffloadStartPlaying(const BluetoothRemoteDevice & device,const std::vector<int32_t> & sessionsId)614 int A2dpSource::OffloadStartPlaying(const BluetoothRemoteDevice &device, const std::vector<int32_t> &sessionsId)
615 {
616     HILOGI("enter, start playing device:%{public}s", GET_ENCRYPT_ADDR(device));
617     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device err");
618     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, BT_ERR_INVALID_PARAM, "invaild mac");
619     CHECK_AND_RETURN_LOG_RET(sessionsId.size() != 0, BT_ERR_INVALID_PARAM, "session size zero.");
620     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
621     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
622     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY,
623         "a2dpSrc proxy is nullptr");
624     return proxy->OffloadStartPlaying(RawAddress(device.GetDeviceAddr()), sessionsId);
625 }
626 
OffloadStopPlaying(const BluetoothRemoteDevice & device,const std::vector<int32_t> & sessionsId)627 int A2dpSource::OffloadStopPlaying(const BluetoothRemoteDevice &device, const std::vector<int32_t> &sessionsId)
628 {
629     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device err");
630     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, BT_ERR_INVALID_PARAM, "invaild mac");
631     CHECK_AND_RETURN_LOG_RET(sessionsId.size() != 0, BT_ERR_INVALID_PARAM, "session size zero.");
632     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
633     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
634     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY,
635         "a2dpSrc proxy is nullptr");
636     return proxy->OffloadStopPlaying(RawAddress(device.GetDeviceAddr()), sessionsId);
637 }
638 
A2dpOffloadSessionRequest(const BluetoothRemoteDevice & device,const std::vector<A2dpStreamInfo> & info)639 int A2dpSource::A2dpOffloadSessionRequest(const BluetoothRemoteDevice &device, const std::vector<A2dpStreamInfo> &info)
640 {
641     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), A2DP_STREAM_ENCODE_UNKNOWN, "device err");
642     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, A2DP_STREAM_ENCODE_UNKNOWN, "invaild mac");
643     CHECK_AND_RETURN_LOG_RET(info.size() != 0, A2DP_STREAM_ENCODE_SOFTWARE, "empty stream");
644     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), A2DP_STREAM_ENCODE_UNKNOWN, "bluetooth is off.");
645     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
646     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, A2DP_STREAM_ENCODE_UNKNOWN, "a2dpSrc proxy is nullptr");
647 
648     std::vector<BluetoothA2dpStreamInfo> streamsInfo = {};
649     BluetoothA2dpStreamInfo streamInfo;
650     for (auto stream : info) {
651         streamInfo.sessionId = stream.sessionId;
652         streamInfo.streamType = stream.streamType;
653         streamInfo.sampleRate = stream.sampleRate;
654         streamInfo.isSpatialAudio = stream.isSpatialAudio;
655         streamsInfo.push_back(streamInfo);
656     }
657     return proxy->A2dpOffloadSessionPathRequest(RawAddress(device.GetDeviceAddr()), streamsInfo);
658 }
659 
A2dpOffloadCodecStatus(const BluetoothA2dpOffloadCodecStatus & status)660 A2dpOffloadCodecStatus::A2dpOffloadCodecStatus(const BluetoothA2dpOffloadCodecStatus &status)
661 {
662     offloadInfo.mediaPacketHeader = status.offloadInfo.mediaPacketHeader;
663     offloadInfo.mPt = status.offloadInfo.mPt;
664     offloadInfo.ssrc = status.offloadInfo.ssrc;
665     offloadInfo.boundaryFlag = status.offloadInfo.boundaryFlag;
666     offloadInfo.broadcastFlag = status.offloadInfo.broadcastFlag;
667     offloadInfo.codecType = status.offloadInfo.codecType;
668     offloadInfo.maxLatency = status.offloadInfo.maxLatency;
669     offloadInfo.scmsTEnable = status.offloadInfo.scmsTEnable;
670     offloadInfo.sampleRate = status.offloadInfo.sampleRate;
671     offloadInfo.encodedAudioBitrate = status.offloadInfo.encodedAudioBitrate;
672     offloadInfo.bitsPerSample = status.offloadInfo.bitsPerSample;
673     offloadInfo.chMode = status.offloadInfo.chMode;
674     offloadInfo.aclHdl = status.offloadInfo.aclHdl;
675     offloadInfo.l2cRcid = status.offloadInfo.l2cRcid;
676     offloadInfo.mtu = status.offloadInfo.mtu;
677     offloadInfo.codecSpecific0 = status.offloadInfo.codecSpecific0;
678     offloadInfo.codecSpecific1 = status.offloadInfo.codecSpecific1;
679     offloadInfo.codecSpecific2 = status.offloadInfo.codecSpecific2;
680     offloadInfo.codecSpecific3 = status.offloadInfo.codecSpecific3;
681     offloadInfo.codecSpecific4 = status.offloadInfo.codecSpecific4;
682     offloadInfo.codecSpecific5 = status.offloadInfo.codecSpecific5;
683     offloadInfo.codecSpecific6 = status.offloadInfo.codecSpecific6;
684     offloadInfo.codecSpecific7 = status.offloadInfo.codecSpecific7;
685 }
686 
GetOffloadCodecStatus(const BluetoothRemoteDevice & device) const687 A2dpOffloadCodecStatus A2dpSource::GetOffloadCodecStatus(const BluetoothRemoteDevice &device) const
688 {
689     HILOGI("enter");
690     A2dpOffloadCodecStatus ret;
691     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), ret, "input device err");
692     CHECK_AND_RETURN_LOG_RET(device.GetDeviceAddr() != INVALID_MAC_ADDRESS, ret, "invaild mac");
693     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), ret, "bluetooth is off.");
694     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
695     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, ret, "a2dpSrc proxy is nullptr");
696     BluetoothA2dpOffloadCodecStatus offloadStatus(proxy->GetOffloadCodecStatus(RawAddress(device.GetDeviceAddr())));
697     A2dpOffloadCodecStatus status(offloadStatus);
698     HILOGI("codecType:%{public}x,mtu:%{public}d", status.offloadInfo.codecType, status.offloadInfo.mtu);
699     return status;
700 }
701 
EnableAutoPlay(const BluetoothRemoteDevice & device)702 int A2dpSource::EnableAutoPlay(const BluetoothRemoteDevice &device)
703 {
704     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "input device err");
705     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
706     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
707     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "a2dpSrc proxy is nullptr");
708     return proxy->EnableAutoPlay(RawAddress(device.GetDeviceAddr()));
709 }
710 
DisableAutoPlay(const BluetoothRemoteDevice & device,const int duration)711 int A2dpSource::DisableAutoPlay(const BluetoothRemoteDevice &device, const int duration)
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->DisableAutoPlay(RawAddress(device.GetDeviceAddr()), duration);
718 }
719 
GetAutoPlayDisabledDuration(const BluetoothRemoteDevice & device,int & duration)720 int A2dpSource::GetAutoPlayDisabledDuration(const BluetoothRemoteDevice &device, 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->GetAutoPlayDisabledDuration(RawAddress(device.GetDeviceAddr()), duration);
727 }
728 
GetVirtualDeviceList(std::vector<std::string> & devices)729 void A2dpSource::GetVirtualDeviceList(std::vector<std::string> &devices)
730 {
731     CHECK_AND_RETURN_LOG(IS_BT_ENABLED(), "bluetooth is off.");
732     sptr<IBluetoothA2dpSrc> proxy = GetRemoteProxy<IBluetoothA2dpSrc>(PROFILE_A2DP_SRC);
733     CHECK_AND_RETURN_LOG(proxy != nullptr, "a2dpSrc proxy is nullptr");
734     proxy->GetVirtualDeviceList(devices);
735 }
736 } // namespace Bluetooth
737 } // namespace OHOS