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