• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "component_manager.h"
17 
18 #include <cinttypes>
19 #include <future>
20 #include <pthread.h>
21 #include <string>
22 #include <thread>
23 
24 #include "ipc_object_stub.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 
28 #include "anonymous_string.h"
29 #include "capability_info_manager.h"
30 #include "component_disable.h"
31 #include "component_enable.h"
32 #include "component_loader.h"
33 #include "constants.h"
34 #include "dh_context.h"
35 #include "dh_utils_hitrace.h"
36 #include "dh_utils_hisysevent.h"
37 #include "dh_utils_tool.h"
38 #include "distributed_hardware_errno.h"
39 #include "distributed_hardware_log.h"
40 #include "enabled_comps_dump.h"
41 #include "low_latency.h"
42 #include "publisher.h"
43 #include "task_executor.h"
44 #include "task_factory.h"
45 #include "version_info_manager.h"
46 #include "version_manager.h"
47 
48 namespace OHOS {
49 namespace DistributedHardware {
50 #undef DH_LOG_TAG
51 #define DH_LOG_TAG "ComponentManager"
52 
53 IMPLEMENT_SINGLE_INSTANCE(ComponentManager);
54 
55 namespace {
56     constexpr int32_t ENABLE_RETRY_MAX_TIMES = 30;
57     constexpr int32_t DISABLE_RETRY_MAX_TIMES = 30;
58     constexpr int32_t ENABLE_PARAM_RETRY_TIME = 500 * 1000;
59     constexpr int32_t INVALID_SA_ID = -1;
60     constexpr int32_t MONITOR_TASK_DELAY_MS = 5 * 1000;
61     const std::string MONITOR_TASK_TIMER_ID = "monitor_task_timer_id";
62 }
63 
ComponentManager()64 ComponentManager::ComponentManager() : compSource_({}), compSink_({}), compSrcSaId_({}),
65     compMonitorPtr_(std::make_shared<ComponentMonitor>()), lowLatencyListener_(new(std::nothrow) LowLatencyListener),
66     monitorTaskTimer_(std::make_shared<MonitorTaskTimer>(MONITOR_TASK_TIMER_ID, MONITOR_TASK_DELAY_MS))
67 {
68     DHLOGI("Ctor ComponentManager");
69 }
70 
~ComponentManager()71 ComponentManager::~ComponentManager()
72 {
73     DHLOGD("Dtor ComponentManager");
74     compMonitorPtr_.reset();
75     compMonitorPtr_ = nullptr;
76     lowLatencyListener_ = nullptr;
77 }
78 
Init()79 int32_t ComponentManager::Init()
80 {
81     DHLOGI("start.");
82     DHTraceStart(COMPONENT_INIT_START);
83     if (!InitCompSource()) {
84         DHLOGE("InitCompSource failed.");
85         DHTraceEnd();
86         return ERR_DH_FWK_COMPONENT_INIT_SOURCE_FAILED;
87     }
88     if (!InitCompSink()) {
89         DHLOGE("InitCompSink failed.");
90         compSource_.clear();
91         DHTraceEnd();
92         return ERR_DH_FWK_COMPONENT_INIT_SINK_FAILED;
93     }
94 
95     if (compMonitorPtr_ == nullptr) {
96         DHLOGE("compMonitorPtr_ is null.");
97         return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
98     }
99     for (const auto &comp : compSource_) {
100         if (compSrcSaId_.find(comp.first) == compSrcSaId_.end()) {
101             continue;
102         }
103         compMonitorPtr_->AddSAMonitor(compSrcSaId_.at(comp.first));
104     }
105 
106     auto sourceResult = StartSource();
107     auto sinkResult = StartSink();
108 
109     if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
110         DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue");
111         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
112             "dhfwk start source failed.");
113     }
114     if (!WaitForResult(Action::START_SINK, sinkResult)) {
115         DHLOGE("StartSink failed, some virtual components maybe cannot work, but want to continue");
116         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
117             "dhfwk start sink failed.");
118     }
119     if (monitorTaskTimer_ != nullptr) {
120         monitorTaskTimer_->StartTimer();
121     }
122 #ifdef DHARDWARE_LOW_LATENCY
123     Publisher::GetInstance().RegisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
124 #endif
125     DHLOGI("Init component success");
126     DHTraceEnd();
127     return DH_FWK_SUCCESS;
128 }
129 
UnInit()130 int32_t ComponentManager::UnInit()
131 {
132     DHLOGI("start.");
133     if (compMonitorPtr_ == nullptr) {
134         DHLOGE("compMonitorPtr_ is null.");
135         return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
136     }
137     for (const auto &comp : compSource_) {
138         if (compSrcSaId_.find(comp.first) == compSrcSaId_.end()) {
139             continue;
140         }
141         compMonitorPtr_->RemoveSAMonitor(compSrcSaId_.at(comp.first));
142     }
143     auto sourceResult = StopSource();
144     auto sinkResult = StopSink();
145 
146     if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
147         DHLOGE("StopSource failed, but want to continue");
148     }
149     if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
150         DHLOGE("StopSource failed, but want to continue");
151     }
152 
153     compSource_.clear();
154     compSink_.clear();
155 
156     if (monitorTaskTimer_ != nullptr) {
157         monitorTaskTimer_->StopTimer();
158     }
159 #ifdef DHARDWARE_LOW_LATENCY
160     Publisher::GetInstance().UnregisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
161     LowLatency::GetInstance().CloseLowLatency();
162 #endif
163     DHLOGI("Release component success");
164     return DH_FWK_SUCCESS;
165 }
166 
StartSource()167 ActionResult ComponentManager::StartSource()
168 {
169     DHLOGI("start.");
170     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
171     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
172     for (const auto &item : compSource_) {
173         CompVersion compversion;
174         VersionManager::GetInstance().GetCompVersion(uuid, item.first, compversion);
175         auto params = compversion.sourceVersion;
176         auto future = std::async(std::launch::async, [item, params]() { return item.second->InitSource(params); });
177         futures.emplace(item.first, future.share());
178     }
179     return futures;
180 }
181 
StartSource(DHType dhType)182 ActionResult ComponentManager::StartSource(DHType dhType)
183 {
184     DHLOGI("Start Source, dhType: %" PRIu32, (uint32_t)dhType);
185     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
186     if (compSource_.find(dhType) == compSource_.end()) {
187         DHLOGE("Component for DHType: %" PRIu32 " not init source handler", (uint32_t)dhType);
188         return futures;
189     }
190 
191     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
192     CompVersion compVersion;
193     VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
194     auto params = compVersion.sourceVersion;
195     auto future = std::async(std::launch::async, [this, dhType, params]() {
196         return compSource_[dhType]->InitSource(params);
197     });
198     futures.emplace(dhType, future.share());
199 
200     return futures;
201 }
202 
StartSink()203 ActionResult ComponentManager::StartSink()
204 {
205     DHLOGI("start.");
206     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
207     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
208     for (const auto &item : compSink_) {
209         CompVersion compversion;
210         VersionManager::GetInstance().GetCompVersion(uuid, item.first, compversion);
211         auto params = compversion.sinkVersion;
212         auto future = std::async(std::launch::async, [item, params]() { return item.second->InitSink(params); });
213         futures.emplace(item.first, future.share());
214     }
215     return futures;
216 }
217 
StartSink(DHType dhType)218 ActionResult ComponentManager::StartSink(DHType dhType)
219 {
220     DHLOGI("Start Sink, dhType: %" PRIu32, (uint32_t)dhType);
221     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
222     if (compSink_.find(dhType) == compSink_.end()) {
223         DHLOGE("Component for DHType: %" PRIu32 " not init sink handler", (uint32_t)dhType);
224         return futures;
225     }
226 
227     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
228     CompVersion compVersion;
229     VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
230     auto params = compVersion.sinkVersion;
231     auto future = std::async(std::launch::async, [this, dhType, params]() {
232         return compSink_[dhType]->InitSink(params);
233     });
234     futures.emplace(dhType, future.share());
235 
236     return futures;
237 }
238 
StopSource()239 ActionResult ComponentManager::StopSource()
240 {
241     DHLOGI("start.");
242     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
243     for (const auto &item : compSource_) {
244         auto future = std::async(std::launch::async, [item]() { return item.second->ReleaseSource(); });
245         futures.emplace(item.first, future.share());
246     }
247     return futures;
248 }
249 
StopSink()250 ActionResult ComponentManager::StopSink()
251 {
252     DHLOGI("start.");
253     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
254     for (const auto &item : compSink_) {
255         auto future = std::async(std::launch::async, [item]() {
256             int32_t status = item.second->ReleaseSink();
257             IHardwareHandler *hardwareHandler = nullptr;
258             status = ComponentLoader::GetInstance().GetHardwareHandler(item.first, hardwareHandler);
259             if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) {
260                 DHLOGE("GetHardwareHandler %#X failed", item.first);
261                 return status;
262             }
263             hardwareHandler->UnRegisterPluginListener();
264             return status;
265         });
266 
267         futures.emplace(item.first, future.share());
268     }
269     return futures;
270 }
271 
WaitForResult(const Action & action,ActionResult actionsResult)272 bool ComponentManager::WaitForResult(const Action &action, ActionResult actionsResult)
273 {
274     DHLOGD("start.");
275     auto ret = true;
276     for (auto &iter : actionsResult) {
277         auto result = iter.second.get();
278         DHLOGI("action = %d, compType = %#X, ret = %d.", static_cast<int32_t>(action), iter.first, result);
279         if (result != DH_FWK_SUCCESS) {
280             ret = false;
281             DHLOGE("there is error, but want to continue.");
282         }
283     }
284     DHLOGD("end.");
285     return ret;
286 }
287 
InitCompSource()288 bool ComponentManager::InitCompSource()
289 {
290     auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
291     for (const auto &type : compTypes) {
292         IDistributedHardwareSource *sourcePtr = nullptr;
293         auto ret = ComponentLoader::GetInstance().GetSource(type, sourcePtr);
294         if (ret != DH_FWK_SUCCESS) {
295             DHLOGW("GetSource failed, compType = %#X, ret = %d.", type, ret);
296             continue;
297         }
298         if (sourcePtr == nullptr) {
299             DHLOGW("sourcePtr is null, compType = %#X.", type);
300             continue;
301         }
302         compSource_.insert(std::make_pair(type, sourcePtr));
303 
304         int32_t saId = ComponentLoader::GetInstance().GetSourceSaId(type);
305         if (saId != INVALID_SA_ID) {
306             compSrcSaId_.insert(std::make_pair(type, saId));
307         }
308     }
309     return !compSource_.empty();
310 }
311 
InitCompSink()312 bool ComponentManager::InitCompSink()
313 {
314     auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
315     for (const auto &type : compTypes) {
316         IDistributedHardwareSink *sinkPtr = nullptr;
317         auto ret = ComponentLoader::GetInstance().GetSink(type, sinkPtr);
318         if (ret != DH_FWK_SUCCESS) {
319             DHLOGW("GetSink failed, compType = %#X, ret = %d.", type, ret);
320             continue;
321         }
322         if (sinkPtr == nullptr) {
323             DHLOGW("sinkPtr is null, compType = %#X.", type);
324             continue;
325         }
326         compSink_.insert(std::make_pair(type, sinkPtr));
327     }
328     return !compSink_.empty();
329 }
330 
Enable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)331 int32_t ComponentManager::Enable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
332     const DHType dhType)
333 {
334     DHLOGI("start.");
335     auto find = compSource_.find(dhType);
336     if (find == compSource_.end()) {
337         DHLOGE("can not find handler for dhId = %s.", GetAnonyString(dhId).c_str());
338         return ERR_DH_FWK_PARA_INVALID;
339     }
340     EnableParam param;
341     auto ret = GetEnableParam(networkId, uuid, dhId, dhType, param);
342     if (ret != DH_FWK_SUCCESS) {
343         DHLOGE("GetEnableParam failed, uuid = %s, dhId = %s, errCode = %d", GetAnonyString(uuid).c_str(),
344             GetAnonyString(dhId).c_str(), ret);
345         for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
346             if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
347                 DHLOGE("device is already offline, no need try GetEnableParam, uuid = %s",
348                     GetAnonyString(uuid).c_str());
349                 return ret;
350             }
351             if (GetEnableParam(networkId, uuid, dhId, dhType, param) == DH_FWK_SUCCESS) {
352                 DHLOGE("GetEnableParam success, retryCount = %d", retryCount);
353                 break;
354             }
355             DHLOGE("GetEnableParam failed, retryCount = %d", retryCount);
356             usleep(ENABLE_PARAM_RETRY_TIME);
357         }
358     }
359 
360     auto compEnable = std::make_shared<ComponentEnable>();
361     auto result = compEnable->Enable(networkId, dhId, param, find->second);
362     if (result != DH_FWK_SUCCESS) {
363         for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
364             if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
365                 DHLOGE("device is already offline, no need try enable, uuid = %s", GetAnonyString(uuid).c_str());
366                 return result;
367             }
368             if (compEnable->Enable(networkId, dhId, param, find->second) == DH_FWK_SUCCESS) {
369                 DHLOGE("enable success, retryCount = %d", retryCount);
370                 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
371                 return DH_FWK_SUCCESS;
372             }
373             DHLOGE("enable failed, retryCount = %d", retryCount);
374         }
375         return result;
376     }
377     DHLOGI("enable result is %d, uuid = %s, dhId = %s", result, GetAnonyString(uuid).c_str(),
378         GetAnonyString(dhId).c_str());
379     EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
380 
381     return result;
382 }
383 
Disable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)384 int32_t ComponentManager::Disable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
385     const DHType dhType)
386 {
387     auto find = compSource_.find(dhType);
388     if (find == compSource_.end()) {
389         DHLOGE("can not find handler for dhId = %s.", dhId.c_str());
390         return ERR_DH_FWK_PARA_INVALID;
391     }
392 
393     auto compDisable = std::make_shared<ComponentDisable>();
394     auto result = compDisable->Disable(networkId, dhId, find->second);
395     if (result != DH_FWK_SUCCESS) {
396         for (int32_t retryCount = 0; retryCount < DISABLE_RETRY_MAX_TIMES; retryCount++) {
397             if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
398                 DHLOGE("device is already online, no need try disable, uuid = %s", GetAnonyString(uuid).c_str());
399                 return result;
400             }
401             if (compDisable->Disable(networkId, dhId, find->second) == DH_FWK_SUCCESS) {
402                 DHLOGE("disable success, retryCount = %d", retryCount);
403                 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
404                 return DH_FWK_SUCCESS;
405             }
406             DHLOGE("disable failed, retryCount = %d", retryCount);
407         }
408         return result;
409     }
410     DHLOGI("disable result is %d, uuid = %s, dhId = %s", result, GetAnonyString(uuid).c_str(),
411         GetAnonyString(dhId).c_str());
412     EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
413 
414     return result;
415 }
416 
GetDHType(const std::string & uuid,const std::string & dhId) const417 DHType ComponentManager::GetDHType(const std::string &uuid, const std::string &dhId) const
418 {
419     std::shared_ptr<CapabilityInfo> capability = nullptr;
420     auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
421     if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
422         return capability->GetDHType();
423     }
424     DHLOGE("get dhType failed, uuid = %s, dhId = %s", GetAnonyString(uuid).c_str(),
425         GetAnonyString(dhId).c_str());
426     return DHType::UNKNOWN;
427 }
428 
GetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,DHType dhType,EnableParam & param)429 int32_t ComponentManager::GetEnableParam(const std::string &networkId, const std::string &uuid,
430     const std::string &dhId, DHType dhType, EnableParam &param)
431 {
432     std::shared_ptr<CapabilityInfo> capability = nullptr;
433     auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
434     if ((ret != DH_FWK_SUCCESS) || (capability == nullptr)) {
435         DHLOGE("GetCapability failed, uuid =%s, dhId = %s, errCode = %d", GetAnonyString(uuid).c_str(),
436             GetAnonyString(dhId).c_str(), ret);
437         return ret;
438     }
439 
440     param.attrs = capability->GetDHAttrs();
441     std::string sinkVersion("");
442     ret = GetSinkVersion(networkId, uuid, dhType, sinkVersion);
443     if (ret != DH_FWK_SUCCESS) {
444         DHLOGE("Get sink version failed, uuid = %s, dhId = %s, dhType = %#X,", GetAnonyString(uuid).c_str(),
445             GetAnonyString(dhId).c_str(), dhType);
446         return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
447     }
448     param.version = sinkVersion;
449     DHLOGI("success. uuid =%s, dhId = %s, version = %s", GetAnonyString(uuid).c_str(),
450         GetAnonyString(dhId).c_str(), param.version.c_str());
451 
452     return DH_FWK_SUCCESS;
453 }
454 
GetSinkVersionFromVerMgr(const std::string & uuid,const DHType dhType,std::string & sinkVersion)455 int32_t ComponentManager::GetSinkVersionFromVerMgr(const std::string &uuid, const DHType dhType,
456     std::string &sinkVersion)
457 {
458     CompVersion compversion;
459     int32_t ret = VersionManager::GetInstance().GetCompVersion(uuid, dhType, compversion);
460     if (ret != DH_FWK_SUCCESS) {
461         DHLOGE("Get sink version from version Manager failed, uuid =%s, dhType = %#X, errCode = %d",
462             GetAnonyString(uuid).c_str(), dhType, ret);
463         return ret;
464     }
465     DHLOGI("Get sink version from version mgr success, sinkVersion = %s, uuid = %s, dhType = %#X",
466         compversion.sinkVersion.c_str(), GetAnonyString(uuid).c_str(), dhType);
467     sinkVersion = compversion.sinkVersion;
468     return DH_FWK_SUCCESS;
469 }
470 
GetSinkVersionFromVerInfoMgr(const std::string & uuid,const DHType dhType,std::string & sinkVersion)471 int32_t ComponentManager::GetSinkVersionFromVerInfoMgr(const std::string &uuid, const DHType dhType,
472     std::string &sinkVersion)
473 {
474     VersionInfo versionInfo;
475     int32_t ret =  VersionInfoManager::GetInstance()->GetVersionInfoByDeviceId(GetDeviceIdByUUID(uuid), versionInfo);
476     if (ret != DH_FWK_SUCCESS) {
477         DHLOGE("Get sink version from Version info Manager failed, uuid =%s, dhType = %#X, errCode = %d",
478             GetAnonyString(uuid).c_str(), dhType, ret);
479         return ret;
480     }
481     auto iter = versionInfo.compVersions.find(dhType);
482     if (iter == versionInfo.compVersions.end()) {
483         DHLOGE("can not find component version for dhType = %d", dhType);
484         return ERR_DH_FWK_COMPONENT_DHTYPE_NOT_FOUND;
485     }
486     DHLOGI("Get SinkVersion from version info mgr success, sinkVersion = %s, uuid = %s, dhType = %#X",
487         iter->second.sinkVersion.c_str(), GetAnonyString(uuid).c_str(), dhType);
488     UpdateVersionCache(uuid, versionInfo);
489     sinkVersion = iter->second.sinkVersion;
490     return DH_FWK_SUCCESS;
491 }
492 
GetSinkVersion(const std::string & networkId,const std::string & uuid,DHType dhType,std::string & sinkVersion)493 int32_t ComponentManager::GetSinkVersion(const std::string &networkId, const std::string &uuid,
494     DHType dhType, std::string &sinkVersion)
495 {
496     int32_t ret = GetSinkVersionFromVerMgr(uuid, dhType, sinkVersion);
497     if ((ret == DH_FWK_SUCCESS) && (!sinkVersion.empty())) {
498         return DH_FWK_SUCCESS;
499     }
500 
501     ret = GetSinkVersionFromVerInfoMgr(uuid, dhType, sinkVersion);
502     if ((ret == DH_FWK_SUCCESS) && (!sinkVersion.empty())) {
503         return DH_FWK_SUCCESS;
504     }
505 
506     return ret;
507 }
508 
UpdateVersionCache(const std::string & uuid,const VersionInfo & versionInfo)509 void ComponentManager::UpdateVersionCache(const std::string &uuid, const VersionInfo &versionInfo)
510 {
511     DHVersion dhVersion;
512     dhVersion.uuid = uuid;
513     dhVersion.dhVersion = versionInfo.dhVersion;
514     dhVersion.compVersions = versionInfo.compVersions;
515     VersionManager::GetInstance().AddDHVersion(uuid, dhVersion);
516 }
517 
DumpLoadedComps(std::set<DHType> & compSourceType,std::set<DHType> & compSinkType)518 void ComponentManager::DumpLoadedComps(std::set<DHType> &compSourceType, std::set<DHType> &compSinkType)
519 {
520     for (auto compSource : compSource_) {
521         compSourceType.emplace(compSource.first);
522     }
523     for (auto compSink : compSink_) {
524         compSinkType.emplace(compSink.first);
525     }
526 }
527 
Recover(DHType dhType)528 void ComponentManager::Recover(DHType dhType)
529 {
530     std::thread(&ComponentManager::DoRecover, this, dhType).detach();
531 }
532 
DoRecover(DHType dhType)533 void ComponentManager::DoRecover(DHType dhType)
534 {
535     int32_t ret = pthread_setname_np(pthread_self(), DO_RECOVER);
536     if (ret != DH_FWK_SUCCESS) {
537         DHLOGE("DoRecover setname failed.");
538     }
539     // step1: restart sa process
540     ReStartSA(dhType);
541     // step2: recover distributed hardware virtual driver
542     RecoverDistributedHardware(dhType);
543 }
544 
ReStartSA(DHType dhType)545 void ComponentManager::ReStartSA(DHType dhType)
546 {
547     DHLOGI("Restart SA for DHType %" PRIu32, (uint32_t)dhType);
548     auto sourceResult = StartSource(dhType);
549     auto sinkResult = StartSink(dhType);
550 
551     if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
552         DHLOGE("ReStartSource failed, DHType: %" PRIu32, (uint32_t)dhType);
553     }
554 
555     if (!WaitForResult(Action::START_SINK, sinkResult)) {
556         DHLOGE("ReStartSink failed, DHType: %" PRIu32, (uint32_t)dhType);
557     }
558     DHLOGI("Finish Restart");
559 }
560 
RecoverDistributedHardware(DHType dhType)561 void ComponentManager::RecoverDistributedHardware(DHType dhType)
562 {
563     CapabilityInfoMap capabilityMap;
564     CapabilityInfoManager::GetInstance()->GetDataByDHType(dhType, capabilityMap);
565     for (const auto &capInfo : capabilityMap) {
566         std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(capInfo.second->GetDeviceId());
567         if (uuid.empty()) {
568             DHLOGE("Can not find uuid by capability deviceId: %s",
569                 GetAnonyString(capInfo.second->GetDeviceId()).c_str());
570             continue;
571         }
572 
573         std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
574         if (networkId.empty()) {
575             DHLOGI("Can not find network id by uuid: %s", GetAnonyString(uuid).c_str());
576             continue;
577         }
578 
579         TaskParam taskParam = {
580             .networkId = networkId,
581             .uuid = uuid,
582             .dhId = capInfo.second->GetDHId(),
583             .dhType = capInfo.second->GetDHType()
584         };
585         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
586         TaskExecutor::GetInstance().PushTask(task);
587     }
588 }
589 } // namespace DistributedHardware
590 } // namespace OHOS
591