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 ¶m)
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