• 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 "device_manager.h"
35 #include "dh_context.h"
36 #include "dh_utils_hitrace.h"
37 #include "dh_utils_hisysevent.h"
38 #include "dh_utils_tool.h"
39 #include "distributed_hardware_errno.h"
40 #include "distributed_hardware_log.h"
41 #include "enabled_comps_dump.h"
42 #include "low_latency.h"
43 #include "publisher.h"
44 #include "task_executor.h"
45 #include "task_factory.h"
46 #include "version_info_manager.h"
47 #include "version_manager.h"
48 
49 namespace OHOS {
50 namespace DistributedHardware {
51 #undef DH_LOG_TAG
52 #define DH_LOG_TAG "ComponentManager"
53 
54 IMPLEMENT_SINGLE_INSTANCE(ComponentManager);
55 
56 namespace {
57     constexpr int32_t ENABLE_RETRY_MAX_TIMES = 3;
58     constexpr int32_t DISABLE_RETRY_MAX_TIMES = 3;
59     constexpr int32_t ENABLE_PARAM_RETRY_TIME = 500 * 1000;
60     constexpr int32_t INVALID_SA_ID = -1;
61     constexpr int32_t MONITOR_TASK_DELAY_MS = 5 * 1000;
62     constexpr int32_t UNINIT_COMPONENT_TIMEOUT_SECONDS = 2;
63     const std::string MONITOR_TASK_TIMER_ID = "monitor_task_timer_id";
64 }
65 
ComponentManager()66 ComponentManager::ComponentManager() : compSource_({}), compSink_({}), compSrcSaId_({}),
67     compMonitorPtr_(std::make_shared<ComponentMonitor>()), lowLatencyListener_(new(std::nothrow) LowLatencyListener),
68     monitorTaskTimer_(std::make_shared<MonitorTaskTimer>(MONITOR_TASK_TIMER_ID, MONITOR_TASK_DELAY_MS)),
69     isUnInitTimeOut_(false)
70 {
71     DHLOGI("Ctor ComponentManager");
72 }
73 
~ComponentManager()74 ComponentManager::~ComponentManager()
75 {
76     DHLOGD("Dtor ComponentManager");
77     compMonitorPtr_.reset();
78     compMonitorPtr_ = nullptr;
79     lowLatencyListener_ = nullptr;
80 }
81 
Init()82 int32_t ComponentManager::Init()
83 {
84     DHLOGI("start.");
85     DHTraceStart(COMPONENT_INIT_START);
86     if (!InitCompSource()) {
87         DHLOGE("InitCompSource failed.");
88         DHTraceEnd();
89         return ERR_DH_FWK_COMPONENT_INIT_SOURCE_FAILED;
90     }
91     if (!InitCompSink()) {
92         DHLOGE("InitCompSink failed.");
93         compSource_.clear();
94         DHTraceEnd();
95         return ERR_DH_FWK_COMPONENT_INIT_SINK_FAILED;
96     }
97 
98     if (compMonitorPtr_ == nullptr) {
99         DHLOGE("compMonitorPtr_ is null.");
100         return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
101     }
102     for (const auto &comp : compSource_) {
103         if (compSrcSaId_.find(comp.first) == compSrcSaId_.end()) {
104             continue;
105         }
106         compMonitorPtr_->AddSAMonitor(compSrcSaId_.at(comp.first));
107     }
108 
109     auto sourceResult = StartSource();
110     auto sinkResult = StartSink();
111 
112     if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
113         DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue");
114         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
115             "dhfwk start source failed.");
116     }
117     if (!WaitForResult(Action::START_SINK, sinkResult)) {
118         DHLOGE("StartSink failed, some virtual components maybe cannot work, but want to continue");
119         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
120             "dhfwk start sink failed.");
121     }
122     if (monitorTaskTimer_ != nullptr) {
123         monitorTaskTimer_->StartTimer();
124     }
125 #ifdef DHARDWARE_LOW_LATENCY
126     Publisher::GetInstance().RegisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
127 #endif
128     DHLOGI("Init component success");
129     DHTraceEnd();
130     return DH_FWK_SUCCESS;
131 }
132 
UnInit()133 int32_t ComponentManager::UnInit()
134 {
135     DHLOGI("start.");
136     if (compMonitorPtr_ == nullptr) {
137         DHLOGE("compMonitorPtr_ is null.");
138         return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
139     }
140     for (const auto &comp : compSource_) {
141         if (compSrcSaId_.find(comp.first) == compSrcSaId_.end()) {
142             continue;
143         }
144         compMonitorPtr_->RemoveSAMonitor(compSrcSaId_.at(comp.first));
145     }
146     auto sourceResult = StopSource();
147     auto sinkResult = StopSink();
148 
149     if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
150         DHLOGE("StopSource failed, but want to continue");
151     }
152     if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
153         DHLOGE("StopSource failed, but want to continue");
154     }
155 
156     compSource_.clear();
157     compSink_.clear();
158 
159     if (monitorTaskTimer_ != nullptr) {
160         monitorTaskTimer_->StopTimer();
161     }
162 #ifdef DHARDWARE_LOW_LATENCY
163     Publisher::GetInstance().UnregisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
164     LowLatency::GetInstance().CloseLowLatency();
165 #endif
166     DHLOGI("Release component success");
167 
168     if (isUnInitTimeOut_.load()) {
169         DHLOGE("Some component stop timeout, FORCE exit!");
170         _Exit(0);
171     }
172 
173     return DH_FWK_SUCCESS;
174 }
175 
StartSource()176 ActionResult ComponentManager::StartSource()
177 {
178     DHLOGI("start.");
179     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
180     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
181     for (const auto &item : compSource_) {
182         CompVersion compversion;
183         VersionManager::GetInstance().GetCompVersion(uuid, item.first, compversion);
184         auto params = compversion.sourceVersion;
185         auto future = std::async(std::launch::async, [item, params]() { return item.second->InitSource(params); });
186         futures.emplace(item.first, future.share());
187     }
188     return futures;
189 }
190 
StartSource(DHType dhType)191 ActionResult ComponentManager::StartSource(DHType dhType)
192 {
193     DHLOGI("Start Source, dhType: %" PRIu32, (uint32_t)dhType);
194     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
195     if (compSource_.find(dhType) == compSource_.end()) {
196         DHLOGE("Component for DHType: %" PRIu32 " not init source handler", (uint32_t)dhType);
197         return futures;
198     }
199 
200     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
201     CompVersion compVersion;
202     VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
203     auto params = compVersion.sourceVersion;
204     auto future = std::async(std::launch::async, [this, dhType, params]() {
205         return compSource_[dhType]->InitSource(params);
206     });
207     futures.emplace(dhType, future.share());
208 
209     return futures;
210 }
211 
StartSink()212 ActionResult ComponentManager::StartSink()
213 {
214     DHLOGI("start.");
215     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
216     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
217     for (const auto &item : compSink_) {
218         CompVersion compversion;
219         VersionManager::GetInstance().GetCompVersion(uuid, item.first, compversion);
220         auto params = compversion.sinkVersion;
221         auto future = std::async(std::launch::async, [item, params]() { return item.second->InitSink(params); });
222         futures.emplace(item.first, future.share());
223         if (cameraCompPrivacy_ == nullptr && item.first == DHType::CAMERA) {
224             cameraCompPrivacy_ = std::make_shared<ComponentPrivacy>();
225             item.second->RegisterPrivacyResources(cameraCompPrivacy_);
226         }
227         if (audioCompPrivacy_ == nullptr && item.first == DHType::AUDIO) {
228             audioCompPrivacy_ = std::make_shared<ComponentPrivacy>();
229             item.second->RegisterPrivacyResources(audioCompPrivacy_);
230         }
231     }
232     return futures;
233 }
234 
StartSink(DHType dhType)235 ActionResult ComponentManager::StartSink(DHType dhType)
236 {
237     DHLOGI("Start Sink, dhType: %" PRIu32, (uint32_t)dhType);
238     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
239     if (compSink_.find(dhType) == compSink_.end()) {
240         DHLOGE("Component for DHType: %" PRIu32 " not init sink handler", (uint32_t)dhType);
241         return futures;
242     }
243 
244     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
245     CompVersion compVersion;
246     VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
247     auto params = compVersion.sinkVersion;
248     auto future = std::async(std::launch::async, [this, dhType, params]() {
249         return compSink_[dhType]->InitSink(params);
250     });
251     futures.emplace(dhType, future.share());
252     if (cameraCompPrivacy_ == nullptr && dhType == DHType::CAMERA) {
253         cameraCompPrivacy_ = std::make_shared<ComponentPrivacy>();
254         compSink_[dhType]->RegisterPrivacyResources(cameraCompPrivacy_);
255     }
256     if (audioCompPrivacy_ == nullptr && dhType == DHType::AUDIO) {
257         audioCompPrivacy_ = std::make_shared<ComponentPrivacy>();
258         compSink_[dhType]->RegisterPrivacyResources(audioCompPrivacy_);
259     }
260 
261     return futures;
262 }
263 
StopSource()264 ActionResult ComponentManager::StopSource()
265 {
266     DHLOGI("start.");
267     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
268     for (const auto &item : compSource_) {
269         auto future = std::async(std::launch::async, [item]() { return item.second->ReleaseSource(); });
270         futures.emplace(item.first, future.share());
271     }
272     return futures;
273 }
274 
StopSink()275 ActionResult ComponentManager::StopSink()
276 {
277     DHLOGI("start.");
278     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
279     for (const auto &item : compSink_) {
280         auto future = std::async(std::launch::async, [item]() {
281             int32_t status = item.second->ReleaseSink();
282             IHardwareHandler *hardwareHandler = nullptr;
283             status = ComponentLoader::GetInstance().GetHardwareHandler(item.first, hardwareHandler);
284             if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) {
285                 DHLOGE("GetHardwareHandler %#X failed", item.first);
286                 return status;
287             }
288             hardwareHandler->UnRegisterPluginListener();
289             return status;
290         });
291 
292         futures.emplace(item.first, future.share());
293     }
294     return futures;
295 }
296 
WaitForResult(const Action & action,ActionResult actionsResult)297 bool ComponentManager::WaitForResult(const Action &action, ActionResult actionsResult)
298 {
299     DHLOGD("start.");
300     auto ret = true;
301     for (auto &iter : actionsResult) {
302         std::future_status status = iter.second.wait_for(std::chrono::seconds(UNINIT_COMPONENT_TIMEOUT_SECONDS));
303         if (status == std::future_status::ready) {
304             auto result = iter.second.get();
305             DHLOGI("action = %d, compType = %#X, READY, ret = %d.", static_cast<int32_t>(action), iter.first, result);
306             if (result != DH_FWK_SUCCESS) {
307                 ret = false;
308                 DHLOGE("there is error, but want to continue.");
309             }
310         }
311 
312         if (status == std::future_status::timeout) {
313             DHLOGI("action = %d, compType = %#X, TIMEOUT", static_cast<int32_t>(action), iter.first);
314             if (action == Action::STOP_SOURCE || action == Action::STOP_SINK) {
315                 isUnInitTimeOut_ = true;
316             }
317         }
318 
319         if (status == std::future_status::deferred) {
320             DHLOGI("action = %d, compType = %#X, DEFERRED", static_cast<int32_t>(action), iter.first);
321         }
322     }
323     DHLOGD("end.");
324     return ret;
325 }
326 
InitCompSource()327 bool ComponentManager::InitCompSource()
328 {
329     auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
330     for (const auto &type : compTypes) {
331         IDistributedHardwareSource *sourcePtr = nullptr;
332         auto ret = ComponentLoader::GetInstance().GetSource(type, sourcePtr);
333         if (ret != DH_FWK_SUCCESS) {
334             DHLOGW("GetSource failed, compType = %#X, ret = %d.", type, ret);
335             continue;
336         }
337         if (sourcePtr == nullptr) {
338             DHLOGW("sourcePtr is null, compType = %#X.", type);
339             continue;
340         }
341         compSource_.insert(std::make_pair(type, sourcePtr));
342 
343         int32_t saId = ComponentLoader::GetInstance().GetSourceSaId(type);
344         if (saId != INVALID_SA_ID) {
345             compSrcSaId_.insert(std::make_pair(type, saId));
346         }
347     }
348     return !compSource_.empty();
349 }
350 
InitCompSink()351 bool ComponentManager::InitCompSink()
352 {
353     auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
354     for (const auto &type : compTypes) {
355         IDistributedHardwareSink *sinkPtr = nullptr;
356         auto ret = ComponentLoader::GetInstance().GetSink(type, sinkPtr);
357         if (ret != DH_FWK_SUCCESS) {
358             DHLOGW("GetSink failed, compType = %#X, ret = %d.", type, ret);
359             continue;
360         }
361         if (sinkPtr == nullptr) {
362             DHLOGW("sinkPtr is null, compType = %#X.", type);
363             continue;
364         }
365         compSink_.insert(std::make_pair(type, sinkPtr));
366     }
367     return !compSink_.empty();
368 }
369 
Enable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)370 int32_t ComponentManager::Enable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
371     const DHType dhType)
372 {
373     DHLOGI("start.");
374     auto find = compSource_.find(dhType);
375     if (find == compSource_.end()) {
376         DHLOGE("can not find handler for dhId = %s.", GetAnonyString(dhId).c_str());
377         return ERR_DH_FWK_PARA_INVALID;
378     }
379     EnableParam param;
380     auto ret = GetEnableParam(networkId, uuid, dhId, dhType, param);
381     if (ret != DH_FWK_SUCCESS) {
382         DHLOGE("GetEnableParam failed, uuid = %s, dhId = %s, errCode = %d", GetAnonyString(uuid).c_str(),
383             GetAnonyString(dhId).c_str(), ret);
384         if (RetryGetEnableParam(networkId, uuid, dhId, dhType, param) != DH_FWK_SUCCESS) {
385             return ret;
386         }
387     }
388     std::string subtype = param.subtype;
389     std::map<std::string, bool> resourceDesc = ComponentLoader::GetInstance().GetCompResourceDesc();
390     if (resourceDesc.find(subtype) == resourceDesc.end()) {
391         DHLOGE("GetCompResourceDesc failed.");
392         return ERR_DH_FWK_RESOURCE_KEY_IS_EMPTY;
393     }
394     bool sensitiveVal = resourceDesc[subtype];
395     bool isSameAuthForm = IsIdenticalAccount(networkId);
396     if (sensitiveVal && !isSameAuthForm) {
397         DHLOGE("Privacy resources must be logged in with the same account.");
398         return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
399     }
400 
401     auto compEnable = std::make_shared<ComponentEnable>();
402     auto result = compEnable->Enable(networkId, dhId, param, find->second);
403     if (result != DH_FWK_SUCCESS) {
404         for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
405             if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
406                 DHLOGE("device is already offline, no need try enable, uuid = %s", GetAnonyString(uuid).c_str());
407                 return result;
408             }
409             if (compEnable->Enable(networkId, dhId, param, find->second) == DH_FWK_SUCCESS) {
410                 DHLOGE("enable success, retryCount = %d", retryCount);
411                 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
412                 return DH_FWK_SUCCESS;
413             }
414             DHLOGE("enable failed, retryCount = %d", retryCount);
415         }
416         return result;
417     }
418     DHLOGI("enable result is %d, uuid = %s, dhId = %s", result, GetAnonyString(uuid).c_str(),
419         GetAnonyString(dhId).c_str());
420     EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
421 
422     return result;
423 }
424 
RetryGetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType,EnableParam & param)425 int32_t ComponentManager::RetryGetEnableParam(const std::string &networkId, const std::string &uuid,
426     const std::string &dhId, const DHType dhType, EnableParam &param)
427 {
428     for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
429         if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
430             DHLOGE("device is already offline, no need try GetEnableParam, uuid = %s",
431                 GetAnonyString(uuid).c_str());
432             return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
433         }
434         if (GetEnableParam(networkId, uuid, dhId, dhType, param) == DH_FWK_SUCCESS) {
435             DHLOGE("GetEnableParam success, retryCount = %d", retryCount);
436             break;
437         }
438         DHLOGE("GetEnableParam failed, retryCount = %d", retryCount);
439         usleep(ENABLE_PARAM_RETRY_TIME);
440     }
441     return DH_FWK_SUCCESS;
442 }
443 
Disable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)444 int32_t ComponentManager::Disable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
445     const DHType dhType)
446 {
447     auto find = compSource_.find(dhType);
448     if (find == compSource_.end()) {
449         DHLOGE("can not find handler for dhId = %s.", dhId.c_str());
450         return ERR_DH_FWK_PARA_INVALID;
451     }
452 
453     auto compDisable = std::make_shared<ComponentDisable>();
454     auto result = compDisable->Disable(networkId, dhId, find->second);
455     if (result != DH_FWK_SUCCESS) {
456         for (int32_t retryCount = 0; retryCount < DISABLE_RETRY_MAX_TIMES; retryCount++) {
457             if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
458                 DHLOGE("device is already online, no need try disable, uuid = %s", GetAnonyString(uuid).c_str());
459                 return result;
460             }
461             if (compDisable->Disable(networkId, dhId, find->second) == DH_FWK_SUCCESS) {
462                 DHLOGE("disable success, retryCount = %d", retryCount);
463                 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
464                 return DH_FWK_SUCCESS;
465             }
466             DHLOGE("disable failed, retryCount = %d", retryCount);
467         }
468         return result;
469     }
470     DHLOGI("disable result is %d, uuid = %s, dhId = %s", result, GetAnonyString(uuid).c_str(),
471         GetAnonyString(dhId).c_str());
472     EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
473 
474     return result;
475 }
476 
GetDHType(const std::string & uuid,const std::string & dhId) const477 DHType ComponentManager::GetDHType(const std::string &uuid, const std::string &dhId) const
478 {
479     std::shared_ptr<CapabilityInfo> capability = nullptr;
480     auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
481     if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
482         return capability->GetDHType();
483     }
484     DHLOGE("get dhType failed, uuid = %s, dhId = %s", GetAnonyString(uuid).c_str(),
485         GetAnonyString(dhId).c_str());
486     return DHType::UNKNOWN;
487 }
488 
GetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,DHType dhType,EnableParam & param)489 int32_t ComponentManager::GetEnableParam(const std::string &networkId, const std::string &uuid,
490     const std::string &dhId, DHType dhType, EnableParam &param)
491 {
492     std::shared_ptr<CapabilityInfo> capability = nullptr;
493     auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
494     if ((ret != DH_FWK_SUCCESS) || (capability == nullptr)) {
495         DHLOGE("GetCapability failed, uuid =%s, dhId = %s, errCode = %d", GetAnonyString(uuid).c_str(),
496             GetAnonyString(dhId).c_str(), ret);
497         return ret;
498     }
499     DeviceInfo sourceDeviceInfo = GetLocalDeviceInfo();
500     std::string sourceNetworkId = DHContext::GetInstance().GetNetworkIdByUUID(sourceDeviceInfo.uuid);
501     std::vector<std::shared_ptr<CapabilityInfo>> sourceCapInfos;
502     std::string sourceDHId;
503     CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(sourceDeviceInfo.deviceId, sourceCapInfos);
504     for (const auto &capInfo : sourceCapInfos) {
505         if (dhType == capInfo->GetDHType()) {
506             param.sourceAttrs = capInfo->GetDHAttrs();
507             sourceDHId = capInfo->GetDHId();
508         }
509     }
510     std::string sourceVersion("");
511     ret = GetVersion(sourceNetworkId, sourceDeviceInfo.uuid, dhType, sourceVersion, false);
512     if (ret != DH_FWK_SUCCESS) {
513         DHLOGE("Get source version failed, uuid = %s, dhId = %s, dhType = %#X,",
514             GetAnonyString(sourceDeviceInfo.uuid).c_str(), GetAnonyString(sourceDHId).c_str(), dhType);
515         return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
516     }
517     param.sourceVersion = sourceVersion;
518     param.sinkAttrs = capability->GetDHAttrs();
519     std::string sinkVersion("");
520     ret = GetVersion(networkId, uuid, dhType, sinkVersion, true);
521     if (ret != DH_FWK_SUCCESS) {
522         DHLOGE("Get sink version failed, uuid = %s, dhId = %s, dhType = %#X,", GetAnonyString(uuid).c_str(),
523             GetAnonyString(dhId).c_str(), dhType);
524         return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
525     }
526     param.sinkVersion = sinkVersion;
527     param.subtype = capability->GetDHSubtype();
528     DHLOGI("success. dhType = %#X, sink uuid =%s, sink dhId = %s, sinVersion = %s, source uuid =%s, source dhId = %s, "
529         "sourceVersion = %s, subtype = %s", dhType, GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(),
530         param.sinkVersion.c_str(), GetAnonyString(sourceDeviceInfo.uuid).c_str(),
531         GetAnonyString(sourceDHId).c_str(), param.sourceVersion.c_str(), param.subtype.c_str());
532 
533     return DH_FWK_SUCCESS;
534 }
535 
GetVersionFromVerMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)536 int32_t ComponentManager::GetVersionFromVerMgr(const std::string &uuid, const DHType dhType,
537     std::string &version, bool isSink)
538 {
539     CompVersion compversion;
540     int32_t ret = VersionManager::GetInstance().GetCompVersion(uuid, dhType, compversion);
541     if (ret != DH_FWK_SUCCESS) {
542         DHLOGE("Get version Manager failed, uuid =%s, dhType = %#X, errCode = %d",
543             GetAnonyString(uuid).c_str(), dhType, ret);
544         return ret;
545     }
546     DHLOGI("Get version mgr success, sinkVersion = %s, sourceVersion = %s,uuid = %s, dhType = %#X",
547         compversion.sinkVersion.c_str(), compversion.sourceVersion.c_str(), GetAnonyString(uuid).c_str(), dhType);
548     version = isSink ? compversion.sinkVersion : compversion.sourceVersion;
549     return DH_FWK_SUCCESS;
550 }
551 
GetVersionFromVerInfoMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)552 int32_t ComponentManager::GetVersionFromVerInfoMgr(const std::string &uuid, const DHType dhType,
553     std::string &version, bool isSink)
554 {
555     VersionInfo versionInfo;
556     int32_t ret =  VersionInfoManager::GetInstance()->GetVersionInfoByDeviceId(GetDeviceIdByUUID(uuid), versionInfo);
557     if (ret != DH_FWK_SUCCESS) {
558         DHLOGE("Get Version info Manager failed, uuid =%s, dhType = %#X, errCode = %d",
559             GetAnonyString(uuid).c_str(), dhType, ret);
560         return ret;
561     }
562     auto iter = versionInfo.compVersions.find(dhType);
563     if (iter == versionInfo.compVersions.end()) {
564         DHLOGE("can not find component version for dhType = %d", dhType);
565         return ERR_DH_FWK_COMPONENT_DHTYPE_NOT_FOUND;
566     }
567     DHLOGI("Get version info mgr success, sinkVersion = %s, sourceVersion = %s, uuid = %s, dhType = %#X",
568         iter->second.sinkVersion.c_str(), iter->second.sourceVersion.c_str(), GetAnonyString(uuid).c_str(), dhType);
569     UpdateVersionCache(uuid, versionInfo);
570     version = isSink ? iter->second.sinkVersion : iter->second.sourceVersion;
571     return DH_FWK_SUCCESS;
572 }
573 
GetVersion(const std::string & networkId,const std::string & uuid,DHType dhType,std::string & version,bool isSink)574 int32_t ComponentManager::GetVersion(const std::string &networkId, const std::string &uuid,
575     DHType dhType, std::string &version, bool isSink)
576 {
577     int32_t ret = GetVersionFromVerMgr(uuid, dhType, version, isSink);
578     if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
579         return DH_FWK_SUCCESS;
580     }
581 
582     ret = GetVersionFromVerInfoMgr(uuid, dhType, version, isSink);
583     if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
584         return DH_FWK_SUCCESS;
585     }
586 
587     return ret;
588 }
589 
UpdateVersionCache(const std::string & uuid,const VersionInfo & versionInfo)590 void ComponentManager::UpdateVersionCache(const std::string &uuid, const VersionInfo &versionInfo)
591 {
592     DHVersion dhVersion;
593     dhVersion.uuid = uuid;
594     dhVersion.dhVersion = versionInfo.dhVersion;
595     dhVersion.compVersions = versionInfo.compVersions;
596     VersionManager::GetInstance().AddDHVersion(uuid, dhVersion);
597 }
598 
DumpLoadedComps(std::set<DHType> & compSourceType,std::set<DHType> & compSinkType)599 void ComponentManager::DumpLoadedComps(std::set<DHType> &compSourceType, std::set<DHType> &compSinkType)
600 {
601     for (auto compSource : compSource_) {
602         compSourceType.emplace(compSource.first);
603     }
604     for (auto compSink : compSink_) {
605         compSinkType.emplace(compSink.first);
606     }
607 }
608 
Recover(DHType dhType)609 void ComponentManager::Recover(DHType dhType)
610 {
611     std::thread(&ComponentManager::DoRecover, this, dhType).detach();
612 }
613 
DoRecover(DHType dhType)614 void ComponentManager::DoRecover(DHType dhType)
615 {
616     int32_t ret = pthread_setname_np(pthread_self(), DO_RECOVER);
617     if (ret != DH_FWK_SUCCESS) {
618         DHLOGE("DoRecover setname failed.");
619     }
620     // step1: restart sa process
621     ReStartSA(dhType);
622     // step2: recover distributed hardware virtual driver
623     RecoverDistributedHardware(dhType);
624 }
625 
ReStartSA(DHType dhType)626 void ComponentManager::ReStartSA(DHType dhType)
627 {
628     DHLOGI("Restart SA for DHType %" PRIu32, (uint32_t)dhType);
629     auto sourceResult = StartSource(dhType);
630     auto sinkResult = StartSink(dhType);
631 
632     if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
633         DHLOGE("ReStartSource failed, DHType: %" PRIu32, (uint32_t)dhType);
634     }
635 
636     if (!WaitForResult(Action::START_SINK, sinkResult)) {
637         DHLOGE("ReStartSink failed, DHType: %" PRIu32, (uint32_t)dhType);
638     }
639     DHLOGI("Finish Restart");
640 }
641 
RecoverDistributedHardware(DHType dhType)642 void ComponentManager::RecoverDistributedHardware(DHType dhType)
643 {
644     CapabilityInfoMap capabilityMap;
645     CapabilityInfoManager::GetInstance()->GetDataByDHType(dhType, capabilityMap);
646     for (const auto &capInfo : capabilityMap) {
647         std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(capInfo.second->GetDeviceId());
648         if (uuid.empty()) {
649             DHLOGE("Can not find uuid by capability deviceId: %s",
650                 GetAnonyString(capInfo.second->GetDeviceId()).c_str());
651             continue;
652         }
653 
654         std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
655         if (networkId.empty()) {
656             DHLOGI("Can not find network id by uuid: %s", GetAnonyString(uuid).c_str());
657             continue;
658         }
659 
660         TaskParam taskParam = {
661             .networkId = networkId,
662             .uuid = uuid,
663             .dhId = capInfo.second->GetDHId(),
664             .dhType = capInfo.second->GetDHType()
665         };
666         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
667         TaskExecutor::GetInstance().PushTask(task);
668     }
669 }
670 
GetDHSinkInstance()671 std::map<DHType, IDistributedHardwareSink*> ComponentManager::GetDHSinkInstance()
672 {
673     return compSink_;
674 }
675 
IsIdenticalAccount(const std::string & networkId)676 bool ComponentManager::IsIdenticalAccount(const std::string &networkId)
677 {
678     DmAuthForm authForm = DmAuthForm::INVALID_TYPE;
679     std::vector<DmDeviceInfo> deviceList;
680     DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
681     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
682         DHLOGE("DeviceList size is invalid!");
683         return false;
684     }
685     for (const auto &deviceInfo : deviceList) {
686         if (std::string(deviceInfo.networkId) == networkId) {
687             authForm = deviceInfo.authForm;
688             break;
689         }
690     }
691     if (authForm == DmAuthForm::IDENTICAL_ACCOUNT) {
692         return true;
693     }
694     return false;
695 }
696 } // namespace DistributedHardware
697 } // namespace OHOS
698