• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bluetooth_def.h"
17 #include "bluetooth_errorcode.h"
18 #include "bluetooth_hitrace.h"
19 #include "bluetooth_log.h"
20 #include "bluetooth_utils_server.h"
21 #include "hisysevent.h"
22 #include "interface_profile_manager.h"
23 #include "interface_profile_a2dp_src.h"
24 #include "remote_observer_list.h"
25 #include "interface_adapter_manager.h"
26 #include "permission_utils.h"
27 #include "bluetooth_a2dp_source_server.h"
28 
29 namespace OHOS {
30 namespace Bluetooth {
31 class A2dpSourceObserver : public IA2dpObserver {
32 public:
33     A2dpSourceObserver() = default;
34     ~A2dpSourceObserver() override = default;
35 
OnConnectionStateChanged(const RawAddress & device,int state)36     void OnConnectionStateChanged(const RawAddress &device, int state) override
37     {
38         HILOGI("addr: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state);
39         if (state == static_cast<int>(BTConnectState::CONNECTED) ||
40             state == static_cast<int>(BTConnectState::DISCONNECTED)) {
41             HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "A2DP_CONNECTED_STATE",
42                 OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "STATE", state);
43         }
44         observers_->ForEach([device, state](sptr<IBluetoothA2dpSourceObserver> observer) {
45             observer->OnConnectionStateChanged(device, state);
46         });
47     }
48 
OnPlayingStatusChaned(const RawAddress & device,int playingState,int error)49     void OnPlayingStatusChaned(const RawAddress &device, int playingState, int error) override
50     {
51         HILOGI("addr: %{public}s, state: %{public}d, error: %{public}d",
52             GET_ENCRYPT_ADDR(device), playingState, error);
53         observers_->ForEach([device, playingState, error](sptr<IBluetoothA2dpSourceObserver> observer) {
54             observer->OnPlayingStatusChanged(device, playingState, error);
55         });
56     }
57 
OnConfigurationChanged(const RawAddress & device,const A2dpSrcCodecInfo & info,int error)58     void OnConfigurationChanged(const RawAddress &device, const A2dpSrcCodecInfo &info, int error) override
59     {
60         HILOGI("addr: %{public}s, error: %{public}d", GET_ENCRYPT_ADDR(device), error);
61         observers_->ForEach([device, info, error](sptr<IBluetoothA2dpSourceObserver> observer) {
62             BluetoothA2dpCodecInfo  tmpInfo {};
63             tmpInfo.bitsPerSample = info.bitsPerSample;
64             tmpInfo.channelMode = info.channelMode;
65             tmpInfo.codecPriority = info.codecPriority;
66             tmpInfo.codecType = info.codecType;
67             tmpInfo.sampleRate = info.sampleRate;
68             tmpInfo.codecSpecific1 = info.codecSpecific1;
69             tmpInfo.codecSpecific2 = info.codecSpecific2;
70             tmpInfo.codecSpecific3 = info.codecSpecific3;
71             tmpInfo.codecSpecific4 = info.codecSpecific4;
72 
73             observer->OnConfigurationChanged(device, tmpInfo, error);
74         });
75     }
76 
SetObserver(RemoteObserverList<IBluetoothA2dpSourceObserver> * observers)77     void SetObserver(RemoteObserverList<IBluetoothA2dpSourceObserver> *observers)
78     {
79         observers_ = observers;
80     }
81 
82 private:
83     RemoteObserverList<IBluetoothA2dpSourceObserver> *observers_;
84 };
85 
86 struct BluetoothA2dpSourceServer::impl {
87     impl();
88     ~impl();
89 
90     /// sys state observer
91     class SystemStateObserver;
92     std::unique_ptr<SystemStateObserver> systemStateObserver_ = nullptr;
93 
94     RemoteObserverList<IBluetoothA2dpSourceObserver> observers_;
95     std::unique_ptr<A2dpSourceObserver> observerImp_{std::make_unique<A2dpSourceObserver>()};
96     IProfileA2dpSrc *a2dpSrcService_ = nullptr;
97 };
98 
99 class BluetoothA2dpSourceServer::impl::SystemStateObserver : public ISystemStateObserver {
100 public:
SystemStateObserver(BluetoothA2dpSourceServer::impl * pimpl)101     SystemStateObserver(BluetoothA2dpSourceServer::impl *pimpl) : pimpl_(pimpl) {};
102     ~SystemStateObserver() override = default;
103 
OnSystemStateChange(const BTSystemState state)104     void OnSystemStateChange(const BTSystemState state) override
105     {
106         IProfileManager *serviceMgr = IProfileManager::GetInstance();
107         if (!pimpl_) {
108             HILOGI("failed: pimpl_ is null");
109             return;
110         }
111 
112         switch (state) {
113             case BTSystemState::ON:
114                 if (serviceMgr != nullptr) {
115                     pimpl_->a2dpSrcService_ =
116                         (IProfileA2dpSrc *)serviceMgr->GetProfileService(PROFILE_NAME_A2DP_SRC);
117                     if (pimpl_->a2dpSrcService_ != nullptr) {
118                         pimpl_->a2dpSrcService_->RegisterObserver(pimpl_->observerImp_.get());
119                     }
120                 }
121                 break;
122             case BTSystemState::OFF:
123                 pimpl_->a2dpSrcService_ = nullptr;
124                 break;
125             default:
126                 break;
127         }
128     }
129 
130 private:
131     BluetoothA2dpSourceServer::impl *pimpl_ = nullptr;
132 };
133 
impl()134 BluetoothA2dpSourceServer::impl::impl()
135 {
136     HILOGI("starts");
137 }
138 
~impl()139 BluetoothA2dpSourceServer::impl::~impl()
140 {
141     HILOGI("starts");
142 }
143 
BluetoothA2dpSourceServer()144 BluetoothA2dpSourceServer::BluetoothA2dpSourceServer()
145 {
146     HILOGI("starts");
147     pimpl = std::make_unique<impl>();
148     pimpl->observerImp_->SetObserver(&(pimpl->observers_));
149     pimpl->systemStateObserver_ = std::make_unique<impl::SystemStateObserver>(pimpl.get());
150     IAdapterManager::GetInstance()->RegisterSystemStateObserver(*(pimpl->systemStateObserver_));
151 
152     IProfileManager *serviceMgr = IProfileManager::GetInstance();
153     if (serviceMgr != nullptr) {
154         pimpl->a2dpSrcService_ = (IProfileA2dpSrc *)serviceMgr->GetProfileService(PROFILE_NAME_A2DP_SRC);
155         if (pimpl->a2dpSrcService_ != nullptr) {
156             pimpl->a2dpSrcService_->RegisterObserver(pimpl->observerImp_.get());
157         }
158     }
159 }
160 
~BluetoothA2dpSourceServer()161 BluetoothA2dpSourceServer::~BluetoothA2dpSourceServer()
162 {
163     HILOGI("starts");
164     IAdapterManager::GetInstance()->DeregisterSystemStateObserver(*(pimpl->systemStateObserver_));
165     if (pimpl->a2dpSrcService_ != nullptr) {
166         pimpl->a2dpSrcService_->DeregisterObserver(pimpl->observerImp_.get());
167     }
168 }
169 
RegisterObserver(const sptr<IBluetoothA2dpSourceObserver> & observer)170 void BluetoothA2dpSourceServer::RegisterObserver(const sptr<IBluetoothA2dpSourceObserver> &observer)
171 {
172     HILOGI("starts");
173     if (observer == nullptr) {
174         HILOGI("observer is null");
175         return;
176     }
177     pimpl->observers_.Register(observer);
178     if (pimpl->a2dpSrcService_ == nullptr) {
179         return;
180     }
181     // During A2DP HDF Registration, check the current status and callback
182     RawAddress device = GetActiveSinkDevice();
183     int state = GetDeviceState((const RawAddress &)device);
184     if (state == static_cast<int>(BTConnectState::CONNECTED)) {
185         HILOGI("onConnectionStateChanged");
186         observer->OnConnectionStateChanged(device, state);
187     }
188 }
189 
DeregisterObserver(const sptr<IBluetoothA2dpSourceObserver> & observer)190 void BluetoothA2dpSourceServer::DeregisterObserver(const sptr<IBluetoothA2dpSourceObserver> &observer)
191 {
192     HILOGI("starts");
193     if (observer == nullptr) {
194         HILOGE("observer is null");
195         return;
196     }
197 
198     if (pimpl != nullptr) {
199         pimpl->observers_.Deregister(observer);
200     }
201 }
202 
Connect(const RawAddress & device)203 int32_t BluetoothA2dpSourceServer::Connect(const RawAddress &device)
204 {
205     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
206     if (PermissionUtils::VerifyDiscoverBluetoothPermission() == PERMISSION_DENIED) {
207         HILOGE("Connect error, check permission failed");
208         return BT_ERR_SYSTEM_PERMISSION_FAILED;
209     }
210     OHOS::Bluetooth::BluetoothHiTrace::BluetoothStartAsyncTrace("A2DP_SRC_CONNECT", 1);
211     int32_t result = pimpl->a2dpSrcService_->Connect(device);
212     OHOS::Bluetooth::BluetoothHiTrace::BluetoothFinishAsyncTrace("A2DP_SRC_CONNECT", 1);
213     return result;
214 }
215 
Disconnect(const RawAddress & device)216 int32_t BluetoothA2dpSourceServer::Disconnect(const RawAddress &device)
217 {
218     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
219     if (PermissionUtils::VerifyDiscoverBluetoothPermission() == PERMISSION_DENIED) {
220         HILOGE("Disconnect error, check permission failed");
221         return BT_ERR_SYSTEM_PERMISSION_FAILED;
222     }
223     return pimpl->a2dpSrcService_->Disconnect(device);
224 }
225 
GetDeviceState(const RawAddress & device)226 int BluetoothA2dpSourceServer::GetDeviceState(const RawAddress &device)
227 {
228     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
229     if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
230         HILOGE("false, check permission failed");
231         return BT_FAILURE;
232     }
233     return pimpl->a2dpSrcService_->GetDeviceState(device);
234 }
235 
GetDevicesByStates(const std::vector<int32_t> & states)236 std::vector<RawAddress> BluetoothA2dpSourceServer::GetDevicesByStates(const std::vector<int32_t> &states)
237 {
238     HILOGI("starts");
239     std::vector<RawAddress> rawDevices;
240     if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
241         HILOGE("false, check permission failed");
242         return rawDevices;
243     }
244     std::vector<int> tmpStates;
245     for (int32_t state : states) {
246         HILOGI("state = %{public}d", state);
247         tmpStates.push_back((int)state);
248     }
249 
250     rawDevices = pimpl->a2dpSrcService_->GetDevicesByStates(tmpStates);
251     return rawDevices;
252 }
253 
GetPlayingState(const RawAddress & device,int & state)254 int32_t BluetoothA2dpSourceServer::GetPlayingState(const RawAddress &device, int &state)
255 {
256     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
257     if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) {
258         HILOGE("false, check permission failed");
259         return BT_ERR_SYSTEM_PERMISSION_FAILED;
260     }
261     int ret = pimpl->a2dpSrcService_->GetPlayingState(device, state);
262     if (ret != BT_SUCCESS) {
263         return BT_ERR_INTERNAL_ERROR;
264     }
265     return BT_SUCCESS;
266 }
267 
SetConnectStrategy(const RawAddress & device,int strategy)268 int BluetoothA2dpSourceServer::SetConnectStrategy(const RawAddress &device, int strategy)
269 {
270     HILOGI("addr: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
271     return pimpl->a2dpSrcService_->SetConnectStrategy(device, strategy);
272 }
273 
GetConnectStrategy(const RawAddress & device)274 int BluetoothA2dpSourceServer::GetConnectStrategy(const RawAddress &device)
275 {
276     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
277     return pimpl->a2dpSrcService_->GetConnectStrategy(device);
278 }
279 
SetActiveSinkDevice(const RawAddress & device)280 int BluetoothA2dpSourceServer::SetActiveSinkDevice(const RawAddress &device)
281 {
282     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
283     return pimpl->a2dpSrcService_->SetActiveSinkDevice(device);
284 }
285 
GetActiveSinkDevice()286 RawAddress BluetoothA2dpSourceServer::GetActiveSinkDevice()
287 {
288     HILOGI("starts");
289     return pimpl->a2dpSrcService_->GetActiveSinkDevice();
290 }
291 
GetCodecStatus(const RawAddress & device)292 BluetoothA2dpCodecStatus BluetoothA2dpSourceServer::GetCodecStatus(const RawAddress &device)
293 {
294     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
295     bluetooth::RawAddress addr(device.GetAddress());
296     bluetooth::A2dpSrcCodecStatus ret;
297     BluetoothA2dpCodecStatus codeStatus;
298     BluetoothA2dpCodecInfo serviceInfo;
299     ret = pimpl->a2dpSrcService_->GetCodecStatus(addr);
300 
301     codeStatus.codecInfo.codecPriority = ret.codecInfo.codecPriority;
302     codeStatus.codecInfo.codecType = ret.codecInfo.codecType;
303     codeStatus.codecInfo.sampleRate = ret.codecInfo.sampleRate;
304     codeStatus.codecInfo.bitsPerSample = ret.codecInfo.bitsPerSample;
305     codeStatus.codecInfo.channelMode = ret.codecInfo.channelMode;
306     codeStatus.codecInfo.codecSpecific1 = ret.codecInfo.codecSpecific1;
307     codeStatus.codecInfo.codecSpecific2 = ret.codecInfo.codecSpecific2;
308     codeStatus.codecInfo.codecSpecific3 = ret.codecInfo.codecSpecific3;
309     codeStatus.codecInfo.codecSpecific4 = ret.codecInfo.codecSpecific4;
310 
311     for (auto it = ret.codecInfoConfirmedCap.begin(); it != ret.codecInfoConfirmedCap.end(); it++) {
312         serviceInfo.codecPriority = it->codecPriority;
313         serviceInfo.codecType = it->codecType;
314         serviceInfo.sampleRate = it->sampleRate;
315         serviceInfo.bitsPerSample = it->bitsPerSample;
316         serviceInfo.channelMode = it->channelMode;
317         serviceInfo.codecSpecific1 = it->codecSpecific1;
318         serviceInfo.codecSpecific2 = it->codecSpecific2;
319         serviceInfo.codecSpecific3 = it->codecSpecific3;
320         serviceInfo.codecSpecific4 = it->codecSpecific4;
321         codeStatus.codecInfoConfirmCap.push_back(serviceInfo);
322     }
323 
324     for (auto it = ret.codecInfoLocalCap.begin(); it != ret.codecInfoLocalCap.end(); it++) {
325         serviceInfo.codecPriority = it->codecPriority;
326         serviceInfo.codecType = it->codecType;
327         serviceInfo.sampleRate = it->sampleRate;
328         serviceInfo.bitsPerSample = it->bitsPerSample;
329         serviceInfo.channelMode = it->channelMode;
330         serviceInfo.codecSpecific1 = it->codecSpecific1;
331         serviceInfo.codecSpecific2 = it->codecSpecific2;
332         serviceInfo.codecSpecific3 = it->codecSpecific3;
333         serviceInfo.codecSpecific4 = it->codecSpecific4;
334         codeStatus.codecInfoLocalCap.push_back(serviceInfo);
335     }
336 
337     return codeStatus;
338 }
339 
SetCodecPreference(const RawAddress & device,const BluetoothA2dpCodecInfo & info)340 int BluetoothA2dpSourceServer::SetCodecPreference(const RawAddress &device, const BluetoothA2dpCodecInfo &info)
341 {
342     HILOGI("BluetoothA2dpSourceServer::SetCodecPreference starts, codecPriority = %{public}u,"
343            "codecPriority = %{public}u, sampleRate = %{public}u, bitsPerSample = %{public}d, "
344            "channelMode = %{public}d, codecSpecific1 = %{public}llu, codecSpecific2 = %{public}llu, "
345            "codecSpecific3 = %{public}llu, codecSpecific4 = %{public}llu",
346            info.codecPriority, info.codecType, info.sampleRate, info.bitsPerSample, info.channelMode,
347            (unsigned long long)info.codecSpecific1, (unsigned long long)info.codecSpecific2,
348            (unsigned long long)info.codecSpecific3, (unsigned long long)info.codecSpecific4);
349     bluetooth::A2dpSrcCodecInfo setInfo;
350 
351     setInfo.bitsPerSample = info.bitsPerSample;
352     setInfo.channelMode = info.channelMode;
353     setInfo.codecPriority = info.codecPriority;
354     setInfo.codecType = info.codecType;
355     setInfo.sampleRate = info.sampleRate;
356     setInfo.codecSpecific1 = info.codecSpecific1;
357     setInfo.codecSpecific2 = info.codecSpecific2;
358     setInfo.codecSpecific3 = info.codecSpecific3;
359     setInfo.codecSpecific4 = info.codecSpecific4;
360 
361     return pimpl->a2dpSrcService_->SetCodecPreference(device, setInfo);
362 }
363 
SwitchOptionalCodecs(const RawAddress & device,bool isEnable)364 void BluetoothA2dpSourceServer::SwitchOptionalCodecs(const RawAddress &device, bool isEnable)
365 {
366     HILOGI("addr: %{public}s, isEnable = %{public}d", GET_ENCRYPT_ADDR(device), isEnable);
367     pimpl->a2dpSrcService_->SwitchOptionalCodecs(device, isEnable);
368 }
369 
GetOptionalCodecsSupportState(const RawAddress & device)370 int BluetoothA2dpSourceServer::GetOptionalCodecsSupportState(const RawAddress &device)
371 {
372     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
373     return pimpl->a2dpSrcService_->GetOptionalCodecsSupportState(device);
374 }
375 
StartPlaying(const RawAddress & device)376 int BluetoothA2dpSourceServer::StartPlaying(const RawAddress &device)
377 {
378     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
379     return pimpl->a2dpSrcService_->StartPlaying(device);
380 }
381 
SuspendPlaying(const RawAddress & device)382 int BluetoothA2dpSourceServer::SuspendPlaying(const RawAddress &device)
383 {
384     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
385     return pimpl->a2dpSrcService_->SuspendPlaying(device);
386 }
387 
StopPlaying(const RawAddress & device)388 int BluetoothA2dpSourceServer::StopPlaying(const RawAddress &device)
389 {
390     HILOGI("addr: %{public}s", GET_ENCRYPT_ADDR(device));
391     return pimpl->a2dpSrcService_->StopPlaying(device);
392 }
393 
WriteFrame(const uint8_t * data,uint32_t size)394 int BluetoothA2dpSourceServer::WriteFrame(const uint8_t *data, uint32_t size)
395 {
396     HILOGI("size = %{public}u", size);
397     return pimpl->a2dpSrcService_->WriteFrame(data, size);
398 }
399 
GetRenderPosition(uint16_t & delayValue,uint16_t & sendDataSize,uint32_t & timeStamp)400 void BluetoothA2dpSourceServer::GetRenderPosition(uint16_t &delayValue, uint16_t &sendDataSize, uint32_t &timeStamp)
401 {
402     HILOGI("starts");
403     pimpl->a2dpSrcService_->GetRenderPosition(delayValue, sendDataSize, timeStamp);
404     HILOGI("delayValue = %{public}hu, sendDataSize = %{public}hu, timeStamp = %{public}u", delayValue, sendDataSize,
405         timeStamp);
406 }
407 
408 }  // namespace Bluetooth
409 }  // namespace OHOS
410