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