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