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