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 "profile_service_manager.h"
17
18 #include <algorithm>
19
20 #include "bt_def.h"
21 #include "log.h"
22
23 #include "adapter_config.h"
24 #include "adapter_manager.h"
25 #include "class_creator.h"
26 #include "profile_info.h"
27 #include "profile_list.h"
28
29 namespace OHOS {
30 namespace bluetooth {
31 class ProfileServicesContextCallback : public utility::IContextCallback {
32 public:
ProfileServicesContextCallback(ProfileServiceManager & psm)33 explicit ProfileServicesContextCallback(ProfileServiceManager &psm) : psm_(psm){};
34 ~ProfileServicesContextCallback() = default;
35
OnEnable(const std::string & name,bool ret)36 void OnEnable(const std::string &name, bool ret)
37 {
38 LOG_DEBUG("%{public}s, name=%{public}s, ret=%{public}d\n", __PRETTY_FUNCTION__, name.c_str(), ret);
39 psm_.OnEnable(name, ret);
40 }
41
OnDisable(const std::string & name,bool ret)42 void OnDisable(const std::string &name, bool ret)
43 {
44 LOG_DEBUG("%{public}s, name=%{public}s, ret=%{public}d\n", __PRETTY_FUNCTION__, name.c_str(), ret);
45 psm_.OnDisable(name, ret);
46 }
47
48 private:
49 ProfileServiceManager &psm_;
50 };
51
52 // static function
53 static std::unique_ptr<ProfileServiceManager> g_profileManager = nullptr;
GetInstance()54 IProfileManager *IProfileManager::GetInstance()
55 {
56 return ProfileServiceManager::GetInstance();
57 }
58
GetInstance()59 ProfileServiceManager *ProfileServiceManager::GetInstance()
60 {
61 if (g_profileManager != nullptr) {
62 return g_profileManager.get();
63 }
64 return nullptr;
65 }
66
Initialize(utility::Dispatcher & dispatch)67 void ProfileServiceManager::Initialize(utility::Dispatcher &dispatch)
68 {
69 if (g_profileManager == nullptr) {
70 g_profileManager = std::make_unique<ProfileServiceManager>(dispatch);
71 }
72 g_profileManager->Start();
73 }
74
Uninitialize()75 void ProfileServiceManager::Uninitialize()
76 {
77 if (g_profileManager != nullptr) {
78 g_profileManager->Stop();
79 }
80 }
81
82 // ProfileServiceManager
83 enum ServiceStateID {
84 TURNING_ON = BTStateID::STATE_TURNING_ON,
85 TURN_ON = BTStateID::STATE_TURN_ON,
86 TURNING_OFF = BTStateID::STATE_TURNING_OFF,
87 TURN_OFF = BTStateID::STATE_TURN_OFF,
88 WAIT_TURN_ON,
89 };
90
91 struct ProfileServiceManager::impl {
implOHOS::bluetooth::ProfileServiceManager::impl92 explicit impl(utility::Dispatcher &dispatch) : dispatcher_(dispatch)
93 {}
94 utility::Dispatcher &dispatcher_;
95 ProfilesList<IProfile *> startedProfiles_ = {};
96 ProfilesList<ServiceStateID> profilesState_ = {};
97 std::unique_ptr<ProfileServicesContextCallback> contextCallback_ = nullptr;
98
99 BT_DISALLOW_COPY_AND_ASSIGN(impl);
100 };
101
ProfileServiceManager(utility::Dispatcher & dispatch)102 ProfileServiceManager::ProfileServiceManager(utility::Dispatcher &dispatch)
103 : pimpl(std::make_unique<ProfileServiceManager::impl>(dispatch))
104 {
105 // context callback create
106 pimpl->contextCallback_ = std::make_unique<ProfileServicesContextCallback>(*this);
107 }
108
~ProfileServiceManager()109 ProfileServiceManager::~ProfileServiceManager()
110 {}
111
Start() const112 void ProfileServiceManager::Start() const
113 {
114 LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
115
116 if (IAdapterManager::GetInstance()->GetClassicAdapterInterface()) {
117 CreateClassicProfileServices();
118 }
119
120 if (IAdapterManager::GetInstance()->GetBleAdapterInterface()) {
121 CreateBleProfileServices();
122 }
123 }
124
CreateClassicProfileServices() const125 void ProfileServiceManager::CreateClassicProfileServices() const
126 {
127 LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
128
129 for (auto &sp : GET_CONFIG_PROFILES(BTTransport::ADAPTER_BREDR)) {
130 IProfile *profile = ClassCreator<IProfile>::NewInstance(sp.name_);
131
132 if (profile != nullptr) {
133 LOG_DEBUG("%{public}s %{public}s", __PRETTY_FUNCTION__, sp.name_.c_str());
134 profile->GetContext()->Initialize();
135 profile->GetContext()->RegisterCallback(*(pimpl->contextCallback_));
136 pimpl->startedProfiles_.SetProfile(BTTransport::ADAPTER_BREDR, sp.name_, profile);
137 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BREDR, sp.name_, ServiceStateID::TURN_OFF);
138 } else {
139 LOG_ERROR("%{public}s is not registered!!!", sp.name_.c_str());
140 }
141 }
142 }
143
CreateBleProfileServices() const144 void ProfileServiceManager::CreateBleProfileServices() const
145 {
146 LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
147
148 for (auto &sp : GET_CONFIG_PROFILES(BTTransport::ADAPTER_BLE)) {
149 // BREDR started the profile
150 IProfile *bredrProfile = nullptr;
151 if (pimpl->startedProfiles_.Find(BTTransport::ADAPTER_BREDR, sp.name_, bredrProfile)) {
152 // BREDR create the profile
153 LOG_DEBUG("%{public}s classic %{public}s", __PRETTY_FUNCTION__, sp.name_.c_str());
154 pimpl->startedProfiles_.SetProfile(BTTransport::ADAPTER_BLE, sp.name_, bredrProfile);
155 // init profilesState_
156 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BLE, sp.name_, ServiceStateID::TURN_OFF);
157 } else {
158 // the profile is not create
159 IProfile *newProfile = ClassCreator<IProfile>::NewInstance(sp.name_);
160 if (newProfile != nullptr) {
161 LOG_DEBUG("%{public}s %{public}s", __PRETTY_FUNCTION__, sp.name_.c_str());
162 newProfile->GetContext()->Initialize();
163 newProfile->GetContext()->RegisterCallback(*(pimpl->contextCallback_));
164 pimpl->startedProfiles_.SetProfile(BTTransport::ADAPTER_BLE, sp.name_, newProfile);
165 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BLE, sp.name_, ServiceStateID::TURN_OFF);
166 } else {
167 LOG_ERROR("%{public}s is not registered!!!", sp.name_.c_str());
168 }
169 }
170 }
171 }
172
Stop() const173 void ProfileServiceManager::Stop() const
174 {
175 LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
176
177 for (auto &sp : GET_SUPPORT_PROFILES()) {
178 IProfile *profile = nullptr;
179 if (pimpl->startedProfiles_.Find(BTTransport::ADAPTER_BREDR, sp.name_, profile)) {
180 profile->GetContext()->Uninitialize();
181 pimpl->startedProfiles_.SetProfile(BTTransport::ADAPTER_BREDR, sp.name_, nullptr);
182 delete profile;
183 } else if (pimpl->startedProfiles_.Find(BTTransport::ADAPTER_BLE, sp.name_, profile)) {
184 profile->GetContext()->Uninitialize();
185 pimpl->startedProfiles_.SetProfile(BTTransport::ADAPTER_BLE, sp.name_, nullptr);
186 delete profile;
187 } else {
188 // Nothing to do
189 }
190 }
191
192 pimpl->startedProfiles_.Clear();
193 pimpl->profilesState_.Clear();
194 }
195
GetProfileService(const std::string & name) const196 IProfile *ProfileServiceManager::GetProfileService(const std::string &name) const
197 {
198 IProfile *profile = nullptr;
199
200 if (pimpl->startedProfiles_.Find(name, profile)) {
201 return profile;
202 } else {
203 return nullptr;
204 }
205 }
206
Enable(const BTTransport transport) const207 bool ProfileServiceManager::Enable(const BTTransport transport) const
208 {
209 LOG_DEBUG("%{public}s transport is %{public}d", __PRETTY_FUNCTION__, transport);
210
211 if (IsAllEnabled(transport)) {
212 LOG_DEBUG("%{public}s OK", __PRETTY_FUNCTION__);
213 AdapterManager::GetInstance()->OnProfileServicesEnableComplete(transport, true);
214 } else {
215 EnableProfiles(transport);
216 if (IsAllEnabled(transport)) {
217 LOG_DEBUG("%{public}s OK", __PRETTY_FUNCTION__);
218 AdapterManager::GetInstance()->OnProfileServicesEnableComplete(transport, true);
219 }
220 }
221 return true;
222 }
223
OnAllEnabled(const BTTransport transport) const224 void ProfileServiceManager::OnAllEnabled(const BTTransport transport) const
225 {
226 LOG_DEBUG("%{public}s %{public}d", __PRETTY_FUNCTION__, transport);
227
228 if (pimpl->startedProfiles_.IsEmpty(transport)) {
229 LOG_DEBUG("%{public}s empty %{public}d", __PRETTY_FUNCTION__, transport);
230 return;
231 }
232
233 FOR_EACH_LIST(it, pimpl->profilesState_, transport)
234 {
235 pimpl->profilesState_.SetProfile(transport, it.first, ServiceStateID::TURN_ON);
236 }
237 }
238
IsAllEnabled(const BTTransport transport) const239 bool ProfileServiceManager::IsAllEnabled(const BTTransport transport) const
240 {
241 if (pimpl->startedProfiles_.IsEmpty(transport)) {
242 LOG_DEBUG("%{public}s empty %{public}d", __PRETTY_FUNCTION__, transport);
243 return true;
244 }
245
246 const bool any = std::any_of(pimpl->profilesState_.GetProfiles(transport)->begin(),
247 pimpl->profilesState_.GetProfiles(transport)->end(),
248 [](const auto &temp) -> bool { return temp.second != ServiceStateID::TURN_ON; });
249
250 if (any) {
251 LOG_DEBUG("%{public}s false %{public}d", __PRETTY_FUNCTION__, transport);
252 return false;
253 }
254 LOG_DEBUG("%{public}s true %{public}d", __PRETTY_FUNCTION__, transport);
255 return true;
256 }
257
EnableProfiles(const BTTransport transport) const258 void ProfileServiceManager::EnableProfiles(const BTTransport transport) const
259 {
260 FOR_EACH_LIST(it, pimpl->profilesState_, transport)
261 {
262 std::string name = it.first;
263 BTTransport otherTransport =
264 (transport == BTTransport::ADAPTER_BREDR) ? BTTransport::ADAPTER_BLE : BTTransport::ADAPTER_BREDR;
265 ServiceStateID otherTransportState = ServiceStateID::TURN_OFF;
266
267 if (pimpl->profilesState_.Find(otherTransport, name, otherTransportState)) {
268 switch (otherTransportState) {
269 case ServiceStateID::TURN_ON:
270 LOG_DEBUG("%{public}s TURN_ON otherTransport %{public}d %{public}s", __PRETTY_FUNCTION__, otherTransport, name.c_str());
271 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::TURN_ON);
272 break;
273 case ServiceStateID::TURNING_OFF:
274 LOG_DEBUG("%{public}s TURNING_OFF otherTransport %{public}d %{public}s", __PRETTY_FUNCTION__, otherTransport, name.c_str());
275 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::WAIT_TURN_ON);
276 break;
277 case ServiceStateID::TURNING_ON:
278 LOG_DEBUG("%{public}s TURNING_ON otherTransport %{public}d %{public}s", __PRETTY_FUNCTION__, otherTransport, name.c_str());
279 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::TURNING_ON);
280 break;
281 default:
282 break;
283 }
284 }
285
286 if (pimpl->profilesState_.Get(transport, name) == ServiceStateID::TURN_OFF) {
287 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::TURNING_ON);
288 LOG_DEBUG("%{public}s transport %{public}d %{public}s enable", __PRETTY_FUNCTION__, transport, name.c_str());
289 IProfile *profile = nullptr;
290 if (pimpl->startedProfiles_.Find(transport, name, profile)) {
291 profile->GetContext()->Enable();
292 } else {
293 LOG_DEBUG("%{public}s startedProfiles_ is not find", __PRETTY_FUNCTION__);
294 }
295 }
296 }
297 }
298
OnEnable(const std::string & name,bool ret) const299 void ProfileServiceManager::OnEnable(const std::string &name, bool ret) const
300 {
301 LOG_DEBUG("%{public}s, name=%{public}s, ret=%{public}d\n", __PRETTY_FUNCTION__, name.c_str(), ret);
302 pimpl->dispatcher_.PostTask(std::bind(&ProfileServiceManager::EnableCompleteProcess, this, name, ret));
303 }
EnableCompleteProcess(const std::string & name,bool ret) const304 void ProfileServiceManager::EnableCompleteProcess(const std::string &name, bool ret) const
305 {
306 ServiceStateID newState = ret ? ServiceStateID::TURN_ON : ServiceStateID::TURN_OFF;
307 std::string profileName = name;
308
309 ServiceStateID state = ServiceStateID::TURN_OFF;
310 if ((pimpl->profilesState_.Find(BTTransport::ADAPTER_BREDR, profileName, state)) &&
311 (state == ServiceStateID::TURNING_ON)) {
312 LOG_DEBUG("%{public}s BREDR %{public}s complete ret %{public}d", __PRETTY_FUNCTION__, profileName.c_str(), ret);
313 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BREDR, profileName, newState);
314 if (!IsProfilesTurning(BTTransport::ADAPTER_BREDR)) {
315 EnableCompleteNotify(BTTransport::ADAPTER_BREDR);
316 }
317 }
318
319 if ((pimpl->profilesState_.Find(BTTransport::ADAPTER_BLE, profileName, state)) &&
320 (state == ServiceStateID::TURNING_ON)) {
321 LOG_DEBUG("%{public}s BLE %{public}s complete ret %{public}d", __PRETTY_FUNCTION__, profileName.c_str(), ret);
322 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BLE, profileName, newState);
323 if (!IsProfilesTurning(BTTransport::ADAPTER_BLE)) {
324 EnableCompleteNotify(BTTransport::ADAPTER_BLE);
325 }
326 }
327 }
328
IsProfilesTurning(const BTTransport transport) const329 bool ProfileServiceManager::IsProfilesTurning(const BTTransport transport) const
330 {
331 if (pimpl->startedProfiles_.IsEmpty(transport)) {
332 LOG_DEBUG("%{public}s empty %{public}d", __PRETTY_FUNCTION__, transport);
333 return false;
334 }
335 const bool any = std::any_of(pimpl->profilesState_.GetProfiles(transport)->begin(),
336 pimpl->profilesState_.GetProfiles(transport)->end(),
337 [](const auto &temp) -> bool {
338 return temp.second != ServiceStateID::TURN_ON && temp.second != ServiceStateID::TURN_OFF;
339 });
340 if (any) {
341 LOG_DEBUG("%{public}s true %{public}d", __PRETTY_FUNCTION__, transport);
342 return true;
343 }
344 LOG_DEBUG("%{public}s false %{public}d", __PRETTY_FUNCTION__, transport);
345 return false;
346 }
347
EnableCompleteNotify(const BTTransport transport) const348 void ProfileServiceManager::EnableCompleteNotify(const BTTransport transport) const
349 {
350 int turnOnProfileCount = std::count_if(pimpl->profilesState_.GetProfiles(transport)->begin(),
351 pimpl->profilesState_.GetProfiles(transport)->end(),
352 [](const auto &temp) -> bool { return temp.second == ServiceStateID::TURN_ON; });
353
354 if (turnOnProfileCount == pimpl->profilesState_.Size(transport)) {
355 LOG_DEBUG("%{public}s OK transport %{public}d turnOnProfileCount %{public}d", __PRETTY_FUNCTION__, transport, turnOnProfileCount);
356 AdapterManager::GetInstance()->OnProfileServicesEnableComplete(transport, true);
357 } else {
358 LOG_DEBUG("%{public}s NG transport %{public}d turnOnProfileCount %{public}d", __PRETTY_FUNCTION__, transport, turnOnProfileCount);
359 AdapterManager::GetInstance()->OnProfileServicesEnableComplete(transport, false);
360 }
361 }
362
Disable(const BTTransport transport) const363 bool ProfileServiceManager::Disable(const BTTransport transport) const
364 {
365 LOG_DEBUG("%{public}s transport is %{public}d", __PRETTY_FUNCTION__, transport);
366
367 if (IsAllDisabled(transport)) {
368 LOG_DEBUG("%{public}s OK", __PRETTY_FUNCTION__);
369 AdapterManager::GetInstance()->OnProfileServicesDisableComplete(transport, true);
370 } else {
371 DisableProfiles(transport);
372 if (IsAllDisabled(transport)) {
373 LOG_DEBUG("%{public}s OK", __PRETTY_FUNCTION__);
374 AdapterManager::GetInstance()->OnProfileServicesDisableComplete(transport, true);
375 }
376 }
377
378 return true;
379 }
380
OnAllDisabled(const BTTransport transport) const381 void ProfileServiceManager::OnAllDisabled(const BTTransport transport) const
382 {
383 LOG_DEBUG("%{public}s %{public}d", __PRETTY_FUNCTION__, transport);
384
385 if (pimpl->startedProfiles_.IsEmpty(transport)) {
386 LOG_DEBUG("%{public}s empty %{public}d", __PRETTY_FUNCTION__, transport);
387 return;
388 }
389
390 FOR_EACH_LIST(it, pimpl->profilesState_, transport)
391 {
392 pimpl->profilesState_.SetProfile(transport, it.first, ServiceStateID::TURN_OFF);
393 }
394 }
395
IsAllDisabled(const BTTransport transport) const396 bool ProfileServiceManager::IsAllDisabled(const BTTransport transport) const
397 {
398 if (pimpl->startedProfiles_.IsEmpty(transport)) {
399 LOG_DEBUG("%{public}s empty %{public}d", __PRETTY_FUNCTION__, transport);
400 return true;
401 }
402
403 const bool any = std::any_of(pimpl->profilesState_.GetProfiles(transport)->begin(),
404 pimpl->profilesState_.GetProfiles(transport)->end(),
405 [](const auto &temp) -> bool { return temp.second != ServiceStateID::TURN_OFF; });
406
407 if (any) {
408 LOG_DEBUG("%{public}s false %{public}d", __PRETTY_FUNCTION__, transport);
409 return false;
410 }
411 LOG_DEBUG("%{public}s true %{public}d", __PRETTY_FUNCTION__, transport);
412 return true;
413 }
414
DisableProfiles(const BTTransport transport) const415 void ProfileServiceManager::DisableProfiles(const BTTransport transport) const
416 {
417 FOR_EACH_LIST(it, pimpl->profilesState_, transport)
418 {
419 ServiceStateID otherTransportState = ServiceStateID::TURN_OFF;
420 BTTransport otherTransport =
421 (transport == BTTransport::ADAPTER_BREDR) ? BTTransport::ADAPTER_BLE : BTTransport::ADAPTER_BREDR;
422 std::string name = it.first;
423
424 if (pimpl->profilesState_.Find(otherTransport, name, otherTransportState)) {
425 switch (otherTransportState) {
426 case ServiceStateID::TURN_ON:
427 case ServiceStateID::TURNING_ON:
428 LOG_DEBUG("%{public}s %{public}d otherTransport %{public}d %{public}s",
429 __PRETTY_FUNCTION__,
430 otherTransportState,
431 otherTransport,
432 name.c_str());
433 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::TURN_OFF);
434 break;
435 default:
436 break;
437 }
438 }
439
440 if (pimpl->profilesState_.Get(transport, name) == ServiceStateID::TURN_ON) {
441 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::TURNING_OFF);
442 LOG_DEBUG("%{public}s transport %{public}d %{public}s disable", __PRETTY_FUNCTION__, transport, name.c_str());
443 IProfile *profile = nullptr;
444 if (pimpl->startedProfiles_.Find(transport, name, profile)) {
445 profile->GetContext()->Disable();
446 }
447 }
448 }
449 }
450
OnDisable(const std::string & name,bool ret) const451 void ProfileServiceManager::OnDisable(const std::string &name, bool ret) const
452 {
453 LOG_DEBUG("%{public}s, name=%{public}s, ret=%{public}d\n", __PRETTY_FUNCTION__, name.c_str(), ret);
454 pimpl->dispatcher_.PostTask(std::bind(&ProfileServiceManager::DisableCompleteProcess, this, name, ret));
455 }
456
DisableCompleteProcess(const std::string & name,bool ret) const457 void ProfileServiceManager::DisableCompleteProcess(const std::string &name, bool ret) const
458 {
459 std::string profileName = name;
460
461 ServiceStateID state = ServiceStateID::TURN_OFF;
462 if ((pimpl->profilesState_.Find(BTTransport::ADAPTER_BREDR, profileName, state)) &&
463 (state == ServiceStateID::TURNING_OFF)) {
464 LOG_DEBUG("%{public}s BREDR %{public}s complete ret %{public}d", __PRETTY_FUNCTION__, profileName.c_str(), ret);
465 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BREDR, profileName, ServiceStateID::TURN_OFF);
466 if (!IsProfilesTurning(BTTransport::ADAPTER_BREDR)) {
467 DisableCompleteNotify(BTTransport::ADAPTER_BREDR);
468 }
469 CheckWaitEnableProfiles(profileName, BTTransport::ADAPTER_BLE);
470 }
471 if ((pimpl->profilesState_.Find(BTTransport::ADAPTER_BLE, profileName, state)) &&
472 (state == ServiceStateID::TURNING_OFF)) {
473 LOG_DEBUG("%{public}s BLE %{public}s complete ret %{public}d", __PRETTY_FUNCTION__, profileName.c_str(), ret);
474 pimpl->profilesState_.SetProfile(BTTransport::ADAPTER_BLE, profileName, ServiceStateID::TURN_OFF);
475 if (!IsProfilesTurning(BTTransport::ADAPTER_BLE)) {
476 DisableCompleteNotify(BTTransport::ADAPTER_BLE);
477 }
478 CheckWaitEnableProfiles(profileName, BTTransport::ADAPTER_BREDR);
479 }
480 }
481
DisableCompleteNotify(const BTTransport transport) const482 void ProfileServiceManager::DisableCompleteNotify(const BTTransport transport) const
483 {
484 int turnOffProfileCount = std::count_if(pimpl->profilesState_.GetProfiles(transport)->begin(),
485 pimpl->profilesState_.GetProfiles(transport)->end(),
486 [](const auto &temp) -> bool { return temp.second == ServiceStateID::TURN_OFF; });
487
488 if (turnOffProfileCount == pimpl->profilesState_.Size(transport)) {
489 LOG_DEBUG(
490 "%{public}s OK transport %{public}d turnOffProfileCount %{public}d", __PRETTY_FUNCTION__, (int)transport, turnOffProfileCount);
491 AdapterManager::GetInstance()->OnProfileServicesDisableComplete(transport, true);
492 } else {
493 LOG_DEBUG(
494 "%{public}s NG transport %{public}d turnOffProfileCount %{public}d", __PRETTY_FUNCTION__, (int)transport, turnOffProfileCount);
495 AdapterManager::GetInstance()->OnProfileServicesDisableComplete(transport, false);
496 }
497 }
498
CheckWaitEnableProfiles(const std::string & name,const BTTransport transport) const499 void ProfileServiceManager::CheckWaitEnableProfiles(const std::string &name, const BTTransport transport) const
500 {
501 ServiceStateID state = ServiceStateID::TURN_OFF;
502 if ((pimpl->profilesState_.Find(transport, name, state)) && (state == ServiceStateID::WAIT_TURN_ON)) {
503 LOG_DEBUG("%{public}s %{public}s ::WAIT_TURN_ON", __PRETTY_FUNCTION__, name.c_str());
504 IProfile *profile = nullptr;
505 if (pimpl->startedProfiles_.Find(transport, name, profile)) {
506 pimpl->profilesState_.SetProfile(transport, name, ServiceStateID::TURNING_ON);
507 profile->GetContext()->Enable();
508 }
509 }
510 }
511
GetProfileServicesSupportedUuids(std::vector<std::string> & uuids) const512 void ProfileServiceManager::GetProfileServicesSupportedUuids(std::vector<std::string> &uuids) const
513 {
514 for (auto &sp : GET_SUPPORT_PROFILES()) {
515 ServiceStateID state = ServiceStateID::TURN_OFF;
516 if (pimpl->profilesState_.Find(BTTransport::ADAPTER_BREDR, sp.name_, state) &&
517 (state == ServiceStateID::TURN_ON) && (sp.uuid_ != "") &&
518 (std::find(uuids.begin(), uuids.end(), sp.uuid_) == uuids.end())) {
519 uuids.push_back(sp.uuid_);
520 }
521 if (pimpl->profilesState_.Find(BTTransport::ADAPTER_BLE, sp.name_, state) &&
522 (state == ServiceStateID::TURN_ON) && (sp.uuid_ != "") &&
523 (std::find(uuids.begin(), uuids.end(), sp.uuid_) == uuids.end())) {
524 uuids.push_back(sp.uuid_);
525 }
526 }
527 }
528
GetProfileServicesList() const529 std::vector<uint32_t> ProfileServiceManager::GetProfileServicesList() const
530 {
531 std::vector<uint32_t> profileServicesList;
532 for (auto &sp : GET_SUPPORT_PROFILES()) {
533 if (pimpl->startedProfiles_.Contains(sp.name_)) {
534 HILOGI("%{public}s", sp.name_.c_str());
535 profileServicesList.push_back(sp.id_);
536 }
537 }
538 return profileServicesList;
539 }
540
GetProfileServiceConnectState(const uint32_t profileID) const541 BTConnectState ProfileServiceManager::GetProfileServiceConnectState(const uint32_t profileID) const
542 {
543 std::string profileName = SupportProfilesInfo::IdToName(profileID);
544 IProfile *profile = nullptr;
545 if (!pimpl->startedProfiles_.Find(profileName, profile)) {
546 return BTConnectState::DISCONNECTED;
547 }
548
549 unsigned int profileStateMask = (unsigned int)profile->GetConnectState();
550 LOG_DEBUG("%{public}s profileStateMask is %{public}d", __PRETTY_FUNCTION__, profileStateMask);
551 if (profileStateMask & PROFILE_STATE_CONNECTED) {
552 return BTConnectState::CONNECTED;
553 } else if (profileStateMask & PROFILE_STATE_CONNECTING) {
554 return BTConnectState::CONNECTING;
555 } else if (profileStateMask & PROFILE_STATE_DISCONNECTING) {
556 return BTConnectState::DISCONNECTING;
557 } else {
558 return BTConnectState::DISCONNECTED;
559 }
560 }
561
GetProfileServicesConnectState() const562 BTConnectState ProfileServiceManager::GetProfileServicesConnectState() const
563 {
564 unsigned int stateMask = 0;
565
566 for (auto &sp : GET_SUPPORT_PROFILES()) {
567 IProfile *profile = nullptr;
568 if (pimpl->startedProfiles_.Find(sp.name_, profile)) {
569 if (sp.name_ != PROFILE_NAME_GATT_CLIENT && sp.name_ != PROFILE_NAME_GATT_SERVER &&
570 sp.name_ != PROFILE_NAME_SPP) {
571 stateMask |= (unsigned int)profile->GetConnectState();
572 }
573 }
574 }
575
576 LOG_DEBUG("%{public}s profileServicesStateMask is %{public}d", __PRETTY_FUNCTION__, stateMask);
577 if (stateMask & PROFILE_STATE_CONNECTED) {
578 return BTConnectState::CONNECTED;
579 } else if (stateMask & PROFILE_STATE_CONNECTING) {
580 return BTConnectState::CONNECTING;
581 } else if (stateMask & PROFILE_STATE_DISCONNECTING) {
582 return BTConnectState::DISCONNECTING;
583 } else {
584 return BTConnectState::DISCONNECTED;
585 }
586 }
587 } // namespace bluetooth
588 } // namespace OHOS