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