• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "ffrt.h"
25 #include "ipc_object_stub.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28 
29 #include "anonymous_string.h"
30 #include "capability_info_manager.h"
31 #include "component_disable.h"
32 #include "component_enable.h"
33 #include "component_loader.h"
34 #include "constants.h"
35 #include "hdf_operate.h"
36 #include "device_manager.h"
37 #include "dh_context.h"
38 #include "dh_data_sync_trigger_listener.h"
39 #include "dh_state_listener.h"
40 #include "dh_utils_hitrace.h"
41 #include "dh_utils_hisysevent.h"
42 #include "dh_utils_tool.h"
43 #include "distributed_hardware_errno.h"
44 #include "distributed_hardware_log.h"
45 #include "enabled_comps_dump.h"
46 #include "local_capability_info_manager.h"
47 #include "low_latency.h"
48 #include "meta_info_manager.h"
49 #include "publisher.h"
50 #include "task_executor.h"
51 #include "task_factory.h"
52 #include "version_info_manager.h"
53 #include "version_manager.h"
54 
55 namespace OHOS {
56 namespace DistributedHardware {
57 #undef DH_LOG_TAG
58 #define DH_LOG_TAG "ComponentManager"
59 
60 IMPLEMENT_SINGLE_INSTANCE(ComponentManager);
61 
62 namespace {
63     constexpr int32_t ENABLE_RETRY_MAX_TIMES = 3;
64     constexpr int32_t DISABLE_RETRY_MAX_TIMES = 3;
65     constexpr int32_t ENABLE_PARAM_RETRY_TIME = 500 * 1000;
66     constexpr int32_t INVALID_SA_ID = -1;
67     constexpr int32_t UNINIT_COMPONENT_TIMEOUT_SECONDS = 2;
68 }
69 
ComponentManager()70 ComponentManager::ComponentManager() : compSource_({}), compSink_({}), compSrcSaId_({}),
71     compMonitorPtr_(std::make_shared<ComponentMonitor>()),
72     lowLatencyListener_(sptr<LowLatencyListener>(new(std::nothrow) LowLatencyListener())),
73     isUnInitTimeOut_(false), dhBizStates_({}), dhStateListener_(std::make_shared<DHStateListener>()),
74     dataSyncTriggerListener_(std::make_shared<DHDataSyncTriggerListener>()),
75     dhCommToolPtr_(std::make_shared<DHCommTool>()), needRefreshTaskParams_({})
76 {
77     DHLOGI("Ctor ComponentManager");
78 }
79 
~ComponentManager()80 ComponentManager::~ComponentManager()
81 {
82     DHLOGD("Dtor ComponentManager");
83     compMonitorPtr_.reset();
84     compMonitorPtr_ = nullptr;
85     lowLatencyListener_ = nullptr;
86 }
87 
Init()88 int32_t ComponentManager::Init()
89 {
90     DHLOGI("start.");
91     DHTraceStart(COMPONENT_INIT_START);
92 #ifdef DHARDWARE_LOW_LATENCY
93     Publisher::GetInstance().RegisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
94 #endif
95     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
96     eventHandler_ = std::make_shared<ComponentManager::ComponentManagerEventHandler>(runner);
97     InitDHCommTool();
98     DHLOGI("Init component success");
99     DHTraceEnd();
100     return DH_FWK_SUCCESS;
101 }
102 
InitDHCommTool()103 void ComponentManager::InitDHCommTool()
104 {
105     if (dhCommToolPtr_ == nullptr) {
106         DHLOGE("DH communication tool ptr is null");
107         return;
108     }
109     DHLOGI("Init DH communication tool");
110     dhCommToolPtr_->Init();
111 }
112 
UnInit()113 int32_t ComponentManager::UnInit()
114 {
115     DHLOGI("start.");
116     StopPrivacy();
117     UnInitDHCommTool();
118 #ifdef DHARDWARE_LOW_LATENCY
119     Publisher::GetInstance().UnregisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
120     LowLatency::GetInstance().CloseLowLatency();
121 #endif
122     DHLOGI("Release component success");
123     if (isUnInitTimeOut_.load()) {
124         DHLOGE("Some component stop timeout, FORCE exit!");
125         _Exit(0);
126     }
127     return DH_FWK_SUCCESS;
128 }
129 
StopPrivacy()130 void ComponentManager::StopPrivacy()
131 {
132     // stop privacy
133     if (cameraCompPrivacy_ != nullptr && cameraCompPrivacy_->GetPageFlag()) {
134         cameraCompPrivacy_->StopPrivacePage("camera");
135         cameraCompPrivacy_->SetPageFlagFalse();
136     }
137 
138     if (audioCompPrivacy_ != nullptr  && audioCompPrivacy_->GetPageFlag()) {
139         audioCompPrivacy_->StopPrivacePage("mic");
140         audioCompPrivacy_->SetPageFlagFalse();
141     }
142 }
143 
UnInitDHCommTool()144 void ComponentManager::UnInitDHCommTool()
145 {
146     if (dhCommToolPtr_ == nullptr) {
147         DHLOGE("DH communication tool ptr is null");
148         return;
149     }
150     DHLOGI("UnInit DH communication tool");
151     dhCommToolPtr_->UnInit();
152 }
153 
StartSource(DHType dhType,ActionResult & sourceResult)154 int32_t ComponentManager::StartSource(DHType dhType, ActionResult &sourceResult)
155 {
156     DHLOGI("Start Source, dhType: %{public}" PRIu32, (uint32_t)dhType);
157     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
158     if (compSource_.find(dhType) == compSource_.end()) {
159         DHLOGE("Component for DHType: %{public}" PRIu32 " not init source handler", (uint32_t)dhType);
160         return ERR_DH_FWK_TYPE_NOT_EXIST;
161     }
162     if (compSource_[dhType] == nullptr) {
163         DHLOGE("comp source ptr is null");
164         return ERR_DH_FWK_SA_HANDLER_IS_NULL;
165     }
166     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
167     CompVersion compVersion;
168     VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
169     auto params = compVersion.sourceVersion;
170     std::promise<int32_t> p;
171     std::future<int32_t> f = p.get_future();
172     std::thread([p = std::move(p), this, dhType, params] () mutable {
173         p.set_value(compSource_[dhType]->InitSource(params));
174     }).detach();
175     sourceResult.emplace(dhType, f.share());
176 
177     return DH_FWK_SUCCESS;
178 }
179 
StartSink(DHType dhType,ActionResult & sinkResult)180 int32_t ComponentManager::StartSink(DHType dhType, ActionResult &sinkResult)
181 {
182     DHLOGI("Start Sink, dhType: %{public}" PRIu32, (uint32_t)dhType);
183     std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
184     std::unordered_map<DHType, std::shared_future<int32_t>> futures;
185     if (compSink_.find(dhType) == compSink_.end()) {
186         DHLOGE("Component for DHType: %{public}" PRIu32 " not init sink handler", (uint32_t)dhType);
187         return ERR_DH_FWK_TYPE_NOT_EXIST;
188     }
189     if (compSink_[dhType] == nullptr) {
190         DHLOGE("comp sink ptr is null");
191         return ERR_DH_FWK_SA_HANDLER_IS_NULL;
192     }
193     std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
194     CompVersion compVersion;
195     VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
196     auto params = compVersion.sinkVersion;
197     std::promise<int32_t> p;
198     std::future<int32_t> f = p.get_future();
199     std::thread([p = std::move(p), this, dhType, params] () mutable {
200         p.set_value(compSink_[dhType]->InitSink(params));
201     }).detach();
202     sinkResult.emplace(dhType, f.share());
203     if (cameraCompPrivacy_ == nullptr && dhType == DHType::CAMERA) {
204         cameraCompPrivacy_ = std::make_shared<ComponentPrivacy>();
205         compSink_[dhType]->RegisterPrivacyResources(cameraCompPrivacy_);
206     }
207     if (audioCompPrivacy_ == nullptr && dhType == DHType::AUDIO) {
208         audioCompPrivacy_ = std::make_shared<ComponentPrivacy>();
209         compSink_[dhType]->RegisterPrivacyResources(audioCompPrivacy_);
210     }
211     return DH_FWK_SUCCESS;
212 }
213 
WaitForResult(const Action & action,ActionResult actionsResult)214 bool ComponentManager::WaitForResult(const Action &action, ActionResult actionsResult)
215 {
216     DHLOGD("start.");
217     auto ret = true;
218     for (auto &iter : actionsResult) {
219         std::future_status status = iter.second.wait_for(std::chrono::seconds(UNINIT_COMPONENT_TIMEOUT_SECONDS));
220         if (status == std::future_status::ready) {
221             auto result = iter.second.get();
222             DHLOGI("action = %{public}d, compType = %{public}#X, READY, ret = %{public}d.",
223                 static_cast<int32_t>(action), iter.first, result);
224             if (result != DH_FWK_SUCCESS) {
225                 ret = false;
226                 DHLOGE("there is error, but want to continue.");
227             }
228         }
229 
230         if (status == std::future_status::timeout) {
231             DHLOGI("action = %{public}d, compType = %{public}#X, TIMEOUT", static_cast<int32_t>(action), iter.first);
232             if (action == Action::STOP_SOURCE || action == Action::STOP_SINK) {
233                 isUnInitTimeOut_ = true;
234             }
235         }
236 
237         if (status == std::future_status::deferred) {
238             DHLOGI("action = %{public}d, compType = %{public}#X, DEFERRED", static_cast<int32_t>(action), iter.first);
239         }
240     }
241     DHLOGD("end.");
242     return ret;
243 }
244 
Enable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType,bool isActive)245 int32_t ComponentManager::Enable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
246     const DHType dhType, bool isActive)
247 {
248     DHLOGI("start.");
249     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
250         return ERR_DH_FWK_PARA_INVALID;
251     }
252     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
253     if (compSource_.find(dhType) == compSource_.end()) {
254         DHLOGE("can not find handler for dhId = %{public}s.", GetAnonyString(dhId).c_str());
255         return ERR_DH_FWK_PARA_INVALID;
256     }
257     EnableParam param;
258     auto ret = GetEnableParam(networkId, uuid, dhId, dhType, param);
259     if (ret != DH_FWK_SUCCESS) {
260         DHLOGE("GetEnableParam failed, uuid = %{public}s, dhId = %{public}s, errCode = %{public}d",
261             GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
262         if (RetryGetEnableParam(networkId, uuid, dhId, dhType, param) != DH_FWK_SUCCESS) {
263             return ret;
264         }
265     }
266     if (!isActive) {
267         ret = CheckSubtypeResource(param.subtype, networkId);
268         if (ret != DH_FWK_SUCCESS) {
269             DHLOGE("CheckSubtypeResource failed, ret = %{public}d.", ret);
270             return ret;
271         }
272     }
273 
274     auto compEnable = std::make_shared<ComponentEnable>();
275     auto result = compEnable->Enable(networkId, dhId, param, (compSource_.find(dhType))->second);
276     if (result != DH_FWK_SUCCESS) {
277         for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
278             if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
279                 DHLOGE("device is already offline, no need try enable, uuid= %{public}s", GetAnonyString(uuid).c_str());
280                 return result;
281             }
282             if (compEnable->Enable(networkId, dhId, param, (compSource_.find(dhType))->second) == DH_FWK_SUCCESS) {
283                 DHLOGE("enable success, retryCount = %{public}d", retryCount);
284                 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
285                 return DH_FWK_SUCCESS;
286             }
287             DHLOGE("enable failed, retryCount = %{public}d", retryCount);
288         }
289         return result;
290     }
291     DHLOGI("enable result is %{public}d, uuid = %{public}s, dhId = %{public}s", result, GetAnonyString(uuid).c_str(),
292         GetAnonyString(dhId).c_str());
293     EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
294 
295     return result;
296 }
297 
CheckSubtypeResource(const std::string & subtype,const std::string & networkId)298 int32_t ComponentManager::CheckSubtypeResource(const std::string &subtype, const std::string &networkId)
299 {
300 #ifdef DHARDWARE_CHECK_RESOURCE
301     std::map<std::string, bool> resourceDesc = ComponentLoader::GetInstance().GetCompResourceDesc();
302     if (resourceDesc.find(subtype) == resourceDesc.end()) {
303         DHLOGE("GetCompResourceDesc failed, subtype: %{public}s", subtype.c_str());
304         return ERR_DH_FWK_RESOURCE_KEY_IS_EMPTY;
305     }
306     if (resourceDesc[subtype] && !IsIdenticalAccount(networkId)) {
307         DHLOGE("Privacy resources must be logged in with the same account.");
308         return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
309     }
310 #endif
311     return DH_FWK_SUCCESS;
312 }
313 
RetryGetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType,EnableParam & param)314 int32_t ComponentManager::RetryGetEnableParam(const std::string &networkId, const std::string &uuid,
315     const std::string &dhId, const DHType dhType, EnableParam &param)
316 {
317     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
318         return ERR_DH_FWK_PARA_INVALID;
319     }
320     for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
321         if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
322             DHLOGE("device is already offline, no need try GetEnableParam, uuid = %{public}s",
323                 GetAnonyString(uuid).c_str());
324             return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
325         }
326         if (GetEnableParam(networkId, uuid, dhId, dhType, param) == DH_FWK_SUCCESS) {
327             DHLOGE("GetEnableParam success, retryCount = %{public}d", retryCount);
328             break;
329         }
330         DHLOGE("GetEnableParam failed, retryCount = %{public}d", retryCount);
331         usleep(ENABLE_PARAM_RETRY_TIME);
332     }
333     return DH_FWK_SUCCESS;
334 }
335 
Disable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)336 int32_t ComponentManager::Disable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
337     const DHType dhType)
338 {
339     DHLOGI("start.");
340     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
341         return ERR_DH_FWK_PARA_INVALID;
342     }
343     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
344     auto find = compSource_.find(dhType);
345     if (find == compSource_.end()) {
346         DHLOGE("can not find handler for dhId = %{public}s.", GetAnonyString(dhId).c_str());
347         return ERR_DH_FWK_PARA_INVALID;
348     }
349 
350     auto compDisable = std::make_shared<ComponentDisable>();
351     auto result = compDisable->Disable(networkId, dhId, find->second);
352     if (result != DH_FWK_SUCCESS) {
353         for (int32_t retryCount = 0; retryCount < DISABLE_RETRY_MAX_TIMES; retryCount++) {
354             if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
355                 DHLOGE("device is already online, no need try disable, uuid = %{public}s",
356                     GetAnonyString(uuid).c_str());
357                 return result;
358             }
359             if (compDisable->Disable(networkId, dhId, find->second) == DH_FWK_SUCCESS) {
360                 DHLOGE("disable success, retryCount = %{public}d", retryCount);
361                 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
362                 return DH_FWK_SUCCESS;
363             }
364             DHLOGE("disable failed, retryCount = %{public}d", retryCount);
365         }
366         return result;
367     }
368     DHLOGI("disable result is %{public}d, uuid = %{public}s, dhId = %{public}s", result, GetAnonyString(uuid).c_str(),
369         GetAnonyString(dhId).c_str());
370     EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
371 
372     return result;
373 }
374 
GetDHType(const std::string & uuid,const std::string & dhId) const375 DHType ComponentManager::GetDHType(const std::string &uuid, const std::string &dhId) const
376 {
377     std::shared_ptr<CapabilityInfo> capability = nullptr;
378     auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
379     if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
380         return capability->GetDHType();
381     }
382     DHLOGE("get dhType failed, uuid = %{public}s, dhId = %{public}s", GetAnonyString(uuid).c_str(),
383         GetAnonyString(dhId).c_str());
384     return DHType::UNKNOWN;
385 }
386 
GetEnableCapParam(const std::string & networkId,const std::string & uuid,DHType dhType,EnableParam & param,std::shared_ptr<CapabilityInfo> capability)387 int32_t ComponentManager::GetEnableCapParam(const std::string &networkId, const std::string &uuid,
388     DHType dhType, EnableParam &param, std::shared_ptr<CapabilityInfo> capability)
389 {
390     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid)) {
391         return ERR_DH_FWK_PARA_INVALID;
392     }
393     DeviceInfo sourceDeviceInfo = GetLocalDeviceInfo();
394     std::vector<std::shared_ptr<CapabilityInfo>> sourceCapInfos;
395     std::string sourceDHId;
396     CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(sourceDeviceInfo.deviceId, sourceCapInfos);
397     for (const auto &capInfo : sourceCapInfos) {
398         if (dhType == capInfo->GetDHType()) {
399             param.sourceAttrs = capInfo->GetDHAttrs();
400             sourceDHId = capInfo->GetDHId();
401         }
402     }
403     std::string sourceVersion("");
404     auto ret = GetVersion(sourceDeviceInfo.uuid, dhType, sourceVersion, false);
405     if (ret != DH_FWK_SUCCESS) {
406         DHLOGE("Get source version failed.");
407         return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
408     }
409     param.sourceVersion = sourceVersion;
410 
411     param.sinkAttrs = capability->GetDHAttrs();
412     std::string sinkVersion("");
413     ret = GetVersion(uuid, dhType, sinkVersion, true);
414     if (ret != DH_FWK_SUCCESS) {
415         DHLOGE("Get sink version failed.");
416         // If Version DB not sync, try get sink version from meta info
417         std::shared_ptr<MetaCapabilityInfo> metaCapPtr = nullptr;
418         ret = MetaInfoManager::GetInstance()->GetMetaCapInfo(DHContext::GetInstance().GetUdidHashIdByUUID(uuid),
419             capability->GetDHId(), metaCapPtr);
420         if ((ret == DH_FWK_SUCCESS) && (metaCapPtr != nullptr)) {
421             sinkVersion = metaCapPtr->GetSinkVersion();
422         } else {
423             return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
424         }
425     }
426     param.sinkVersion = sinkVersion;
427     param.subtype = capability->GetDHSubtype();
428     DHLOGI("GetEnableCapParam success. dhType = %{public}#X, sink uuid =%{public}s,"
429         "sinVersion = %{public}s, source uuid =%{public}s, source dhId = %{public}s, sourceVersion = %{public}s,"
430         "subtype = %{public}s", dhType, GetAnonyString(uuid).c_str(),
431         param.sinkVersion.c_str(), GetAnonyString(sourceDeviceInfo.uuid).c_str(), GetAnonyString(sourceDHId).c_str(),
432         param.sourceVersion.c_str(), param.subtype.c_str());
433     return DH_FWK_SUCCESS;
434 }
435 
GetEnableMetaParam(const std::string & networkId,const std::string & uuid,DHType dhType,EnableParam & param,std::shared_ptr<MetaCapabilityInfo> metaCapPtr)436 int32_t ComponentManager::GetEnableMetaParam(const std::string &networkId, const std::string &uuid,
437     DHType dhType, EnableParam &param, std::shared_ptr<MetaCapabilityInfo> metaCapPtr)
438 {
439     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid)) {
440         return ERR_DH_FWK_PARA_INVALID;
441     }
442     DeviceInfo sourceDeviceInfo = GetLocalDeviceInfo();
443     std::vector<std::shared_ptr<MetaCapabilityInfo>> sourceMetaInfos;
444     std::string sourceDHId;
445     MetaInfoManager::GetInstance()->GetMetaCapInfosByUdidHash(sourceDeviceInfo.udidHash, sourceMetaInfos);
446     for (const auto &metaInfo : sourceMetaInfos) {
447         if (dhType == metaInfo->GetDHType()) {
448             param.sourceAttrs = metaInfo->GetDHAttrs();
449             sourceDHId = metaInfo->GetDHId();
450         }
451     }
452     std::string sourceVersion("");
453     auto ret = GetVersion(sourceDeviceInfo.uuid, dhType, sourceVersion, false);
454     if (ret != DH_FWK_SUCCESS) {
455         DHLOGE("Get source version failed.");
456         return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
457     }
458     param.sourceVersion = sourceVersion;
459 
460     param.sinkAttrs = metaCapPtr->GetDHAttrs();
461     param.sinkVersion = metaCapPtr->GetSinkVersion();
462     param.subtype = metaCapPtr->GetDHSubtype();
463     DHLOGI("GetEnableCapParam success. dhType = %{public}#X, sink uuid =%{public}s,"
464         "sinVersion = %{public}s, source uuid =%{public}s, source dhId = %{public}s, sourceVersion = %{public}s,"
465         "subtype = %{public}s", dhType, GetAnonyString(uuid).c_str(),
466         param.sinkVersion.c_str(), GetAnonyString(sourceDeviceInfo.uuid).c_str(), GetAnonyString(sourceDHId).c_str(),
467         param.sourceVersion.c_str(), param.subtype.c_str());
468     return DH_FWK_SUCCESS;
469 }
470 
GetCapParam(const std::string & uuid,const std::string & dhId,std::shared_ptr<CapabilityInfo> & capability)471 int32_t ComponentManager::GetCapParam(const std::string &uuid, const std::string &dhId,
472     std::shared_ptr<CapabilityInfo> &capability)
473 {
474     if (!IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
475         return ERR_DH_FWK_PARA_INVALID;
476     }
477     std::string deviceId = GetDeviceIdByUUID(uuid);
478     auto ret = CapabilityInfoManager::GetInstance()->GetCapability(deviceId, dhId, capability);
479     if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
480         DHLOGI("GetCapability success, deviceId: %{public}s, uuid: %{public}s, dhId: %{public}s, ret: %{public}d",
481             GetAnonyString(deviceId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
482         return ret;
483     }
484 
485     ret = LocalCapabilityInfoManager::GetInstance()->GetCapability(deviceId, dhId, capability);
486     if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
487         DHLOGI("Local GetCaps success, deviceId: %{public}s, uuid: %{public}s, dhId: %{public}s, ret: %{public}d",
488             GetAnonyString(deviceId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
489         return ret;
490     }
491 
492     return ret;
493 }
494 
GetMetaParam(const std::string & uuid,const std::string & dhId,std::shared_ptr<MetaCapabilityInfo> & metaCapPtr)495 int32_t ComponentManager::GetMetaParam(const std::string &uuid, const std::string &dhId,
496     std::shared_ptr<MetaCapabilityInfo> &metaCapPtr)
497 {
498     if (!IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
499         return ERR_DH_FWK_PARA_INVALID;
500     }
501     auto ret = MetaInfoManager::GetInstance()->GetMetaCapInfo(DHContext::GetInstance().GetUdidHashIdByUUID(uuid),
502         dhId, metaCapPtr);
503     if ((ret == DH_FWK_SUCCESS) && (metaCapPtr != nullptr)) {
504         DHLOGI("GetCapability success, uuid =%{public}s, dhId = %{public}s, errCode = %{public}d",
505             GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
506         return ret;
507     }
508     return ret;
509 }
510 
GetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,DHType dhType,EnableParam & param)511 int32_t ComponentManager::GetEnableParam(const std::string &networkId, const std::string &uuid,
512     const std::string &dhId, DHType dhType, EnableParam &param)
513 {
514     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
515         return ERR_DH_FWK_COMPONENT_GET_ENABLE_PARAM_FAILED;
516     }
517     DHLOGI("GetEnableParam start, networkId= %{public}s, uuid = %{public}s, dhId = %{public}s, dhType = %{public}#X,",
518         GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), dhType);
519     std::shared_ptr<CapabilityInfo> capability = nullptr;
520     if (GetCapParam(uuid, dhId, capability) == DH_FWK_SUCCESS) {
521         auto ret = GetEnableCapParam(networkId, uuid, dhType, param, capability);
522         if (ret == DH_FWK_SUCCESS) {
523             return ret;
524         }
525         DHLOGE("GetEnableCapParam failed.");
526     }
527 
528     std::shared_ptr<MetaCapabilityInfo> metaCapPtr = nullptr;
529     if (GetMetaParam(uuid, dhId, metaCapPtr) == DH_FWK_SUCCESS) {
530         auto ret = GetEnableMetaParam(networkId, uuid, dhType, param, metaCapPtr);
531         if (ret == DH_FWK_SUCCESS) {
532             return ret;
533         }
534         DHLOGE("GetEnableMetaParam failed.");
535     }
536     DHLOGE("GetEnableParam is failed.");
537     return ERR_DH_FWK_COMPONENT_GET_ENABLE_PARAM_FAILED;
538 }
539 
GetVersionFromVerMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)540 int32_t ComponentManager::GetVersionFromVerMgr(const std::string &uuid, const DHType dhType,
541     std::string &version, bool isSink)
542 {
543     if (!IsIdLengthValid(uuid)) {
544         return ERR_DH_FWK_PARA_INVALID;
545     }
546     CompVersion compversion;
547     int32_t ret = VersionManager::GetInstance().GetCompVersion(uuid, dhType, compversion);
548     if (ret != DH_FWK_SUCCESS) {
549         DHLOGE("Get version Manager failed, uuid =%{public}s, dhType = %{public}#X, errCode = %{public}d",
550             GetAnonyString(uuid).c_str(), dhType, ret);
551         return ret;
552     }
553     DHLOGI("Get version mgr success, sinkVersion = %{public}s, sourceVersion = %{public}s,uuid = %{public}s, "
554         "dhType = %{public}#X", compversion.sinkVersion.c_str(), compversion.sourceVersion.c_str(),
555         GetAnonyString(uuid).c_str(), dhType);
556     version = isSink ? compversion.sinkVersion : compversion.sourceVersion;
557     return DH_FWK_SUCCESS;
558 }
559 
GetVersionFromVerInfoMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)560 int32_t ComponentManager::GetVersionFromVerInfoMgr(const std::string &uuid, const DHType dhType,
561     std::string &version, bool isSink)
562 {
563     if (!IsIdLengthValid(uuid)) {
564         return ERR_DH_FWK_PARA_INVALID;
565     }
566     VersionInfo versionInfo;
567     int32_t ret =  VersionInfoManager::GetInstance()->GetVersionInfoByDeviceId(GetDeviceIdByUUID(uuid), versionInfo);
568     if (ret != DH_FWK_SUCCESS) {
569         DHLOGE("Get Version info Manager failed, uuid =%{public}s, dhType = %{public}#X, errCode = %{public}d",
570             GetAnonyString(uuid).c_str(), dhType, ret);
571         return ret;
572     }
573     auto iter = versionInfo.compVersions.find(dhType);
574     if (iter == versionInfo.compVersions.end()) {
575         DHLOGE("can not find component version for dhType = %{public}d", dhType);
576         return ERR_DH_FWK_COMPONENT_DHTYPE_NOT_FOUND;
577     }
578     DHLOGI("Get version info mgr success, sinkVersion = %{public}s, sourceVersion = %{public}s, uuid = %{public}s, "
579         "dhType = %{public}#X", iter->second.sinkVersion.c_str(), iter->second.sourceVersion.c_str(),
580         GetAnonyString(uuid).c_str(), dhType);
581     UpdateVersionCache(uuid, versionInfo);
582     version = isSink ? iter->second.sinkVersion : iter->second.sourceVersion;
583     return DH_FWK_SUCCESS;
584 }
585 
GetVersion(const std::string & uuid,DHType dhType,std::string & version,bool isSink)586 int32_t ComponentManager::GetVersion(const std::string &uuid, DHType dhType, std::string &version, bool isSink)
587 {
588     if (!IsIdLengthValid(uuid)) {
589         return ERR_DH_FWK_PARA_INVALID;
590     }
591     int32_t ret = GetVersionFromVerMgr(uuid, dhType, version, isSink);
592     if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
593         return DH_FWK_SUCCESS;
594     }
595 
596     ret = GetVersionFromVerInfoMgr(uuid, dhType, version, isSink);
597     if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
598         return DH_FWK_SUCCESS;
599     }
600 
601     return ret;
602 }
603 
UpdateVersionCache(const std::string & uuid,const VersionInfo & versionInfo)604 void ComponentManager::UpdateVersionCache(const std::string &uuid, const VersionInfo &versionInfo)
605 {
606     if (!IsIdLengthValid(uuid)) {
607         return;
608     }
609     DHVersion dhVersion;
610     dhVersion.uuid = uuid;
611     dhVersion.dhVersion = versionInfo.dhVersion;
612     dhVersion.compVersions = versionInfo.compVersions;
613     VersionManager::GetInstance().AddDHVersion(uuid, dhVersion);
614 }
615 
DumpLoadedCompsource(std::set<DHType> & compSourceType)616 void ComponentManager::DumpLoadedCompsource(std::set<DHType> &compSourceType)
617 {
618     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
619     for (auto compSource : compSource_) {
620         compSourceType.emplace(compSource.first);
621     }
622 }
623 
DumpLoadedCompsink(std::set<DHType> & compSinkType)624 void ComponentManager::DumpLoadedCompsink(std::set<DHType> &compSinkType)
625 {
626     std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
627     for (auto compSink : compSink_) {
628         compSinkType.emplace(compSink.first);
629     }
630 }
631 
Recover(DHType dhType)632 void ComponentManager::Recover(DHType dhType)
633 {
634     ffrt::submit([this, dhType]() { this->DoRecover(dhType); });
635 }
636 
DoRecover(DHType dhType)637 void ComponentManager::DoRecover(DHType dhType)
638 {
639     int32_t ret = pthread_setname_np(pthread_self(), DO_RECOVER);
640     if (ret != DH_FWK_SUCCESS) {
641         DHLOGE("DoRecover setname failed.");
642     }
643     // reset enable status
644     DHLOGI("Reset enable status for DHType %{public}" PRIu32, (uint32_t)dhType);
645     ResetSinkEnableStatus(dhType);
646     ResetSourceEnableStatus(dhType);
647     // recover distributed hardware virtual driver
648     DHLOGI("Recover distributed hardware virtual driver for DHType %{public}" PRIu32, (uint32_t)dhType);
649     RecoverAutoEnableSink(dhType);
650     RecoverAutoEnableSource(dhType);
651     RecoverActiveEnableSink(dhType);
652     RecoverActiveEnableSource(dhType);
653 }
654 
GetDHSinkInstance()655 std::map<DHType, IDistributedHardwareSink*> ComponentManager::GetDHSinkInstance()
656 {
657     std::shared_lock<std::shared_mutex> lock(compSinkMutex_);
658     return compSink_;
659 }
660 
IsIdenticalAccount(const std::string & networkId)661 bool ComponentManager::IsIdenticalAccount(const std::string &networkId)
662 {
663     if (!IsIdLengthValid(networkId)) {
664         return false;
665     }
666     DmAuthForm authForm = DmAuthForm::INVALID_TYPE;
667     std::vector<DmDeviceInfo> deviceList;
668     DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
669     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
670         DHLOGE("DeviceList size is invalid!");
671         return false;
672     }
673     for (const auto &deviceInfo : deviceList) {
674         if (std::string(deviceInfo.networkId) == networkId) {
675             authForm = deviceInfo.authForm;
676             break;
677         }
678     }
679     if (authForm == DmAuthForm::IDENTICAL_ACCOUNT) {
680         return true;
681     }
682     return false;
683 }
684 
UpdateBusinessState(const std::string & networkId,const std::string & dhId,BusinessState state)685 void ComponentManager::UpdateBusinessState(const std::string &networkId, const std::string &dhId, BusinessState state)
686 {
687     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(dhId)) {
688         return;
689     }
690     DHLOGI("UpdateBusinessState, networkId: %{public}s, dhId: %{public}s, state: %{public}" PRIu32,
691         GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str(), (uint32_t)state);
692     {
693         std::lock_guard<std::mutex> lock(bizStateMtx_);
694         dhBizStates_[{networkId, dhId}] = state;
695     }
696 
697     if (state == BusinessState::IDLE) {
698         TaskParam taskParam;
699         if (!FetchNeedRefreshTask({networkId, dhId}, taskParam)) {
700             return;
701         }
702         DHLOGI("The dh need refresh, networkId: %{public}s, dhId: %{public}s",
703             GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str());
704         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
705         TaskExecutor::GetInstance().PushTask(task);
706     }
707 }
708 
GetDHSourceInstance(DHType dhType)709 IDistributedHardwareSource* ComponentManager::GetDHSourceInstance(DHType dhType)
710 {
711     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
712     if (compSource_.find(dhType) == compSource_.end()) {
713         DHLOGE("can not find handler for dhType = %{public}d.", dhType);
714         return nullptr;
715     }
716     return compSource_[dhType];
717 }
718 
QueryBusinessState(const std::string & uuid,const std::string & dhId)719 BusinessState ComponentManager::QueryBusinessState(const std::string &uuid, const std::string &dhId)
720 {
721     if (!IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
722         return BusinessState::UNKNOWN;
723     }
724     std::lock_guard<std::mutex> lock(bizStateMtx_);
725     std::pair<std::string, std::string> key = {uuid, dhId};
726     if (dhBizStates_.find(key) == dhBizStates_.end()) {
727         return BusinessState::UNKNOWN;
728     }
729 
730     return dhBizStates_.at(key);
731 }
732 
TriggerFullCapsSync(const std::string & networkId)733 void ComponentManager::TriggerFullCapsSync(const std::string &networkId)
734 {
735     if (!IsIdLengthValid(networkId)) {
736         return;
737     }
738     if (dhCommToolPtr_ == nullptr) {
739         DHLOGE("DH communication tool ptr is null");
740         return;
741     }
742     dhCommToolPtr_->TriggerReqFullDHCaps(networkId);
743 }
744 
SaveNeedRefreshTask(const TaskParam & taskParam)745 void ComponentManager::SaveNeedRefreshTask(const TaskParam &taskParam)
746 {
747     std::lock_guard<std::mutex> lock(needRefreshTaskParamsMtx_);
748     needRefreshTaskParams_[{taskParam.networkId, taskParam.dhId}] = taskParam;
749 }
750 
FetchNeedRefreshTask(const std::pair<std::string,std::string> & taskKey,TaskParam & taskParam)751 bool ComponentManager::FetchNeedRefreshTask(const std::pair<std::string, std::string> &taskKey, TaskParam &taskParam)
752 {
753     std::lock_guard<std::mutex> lock(needRefreshTaskParamsMtx_);
754     if (needRefreshTaskParams_.find(taskKey) == needRefreshTaskParams_.end()) {
755         return false;
756     }
757 
758     taskParam = needRefreshTaskParams_.at(taskKey);
759     needRefreshTaskParams_.erase(taskKey);
760     return true;
761 }
762 
ComponentManagerEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner)763 ComponentManager::ComponentManagerEventHandler::ComponentManagerEventHandler(
764     const std::shared_ptr<AppExecFwk::EventRunner> runner) : AppExecFwk::EventHandler(runner)
765 {
766     DHLOGI("Ctor ComponentManagerEventHandler");
767 }
768 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)769 void ComponentManager::ComponentManagerEventHandler::ProcessEvent(
770     const AppExecFwk::InnerEvent::Pointer &event)
771 {
772     if (event == nullptr) {
773         DHLOGE("event is nullptr");
774         return;
775     }
776     uint32_t eventId = event->GetInnerEventId();
777     switch (eventId) {
778         case EVENT_DATA_SYNC_MANUAL: {
779             // do muanul sync with remote
780             auto sharedObjPtr = event->GetSharedObject<std::string>();
781             if (sharedObjPtr == nullptr) {
782                 DHLOGE("The data sync param invalid!");
783                 break;
784             }
785             std::string networkId = *sharedObjPtr;
786             DHLOGI("Try receive full capabiliy info from networkId: %{public}s", GetAnonyString(networkId).c_str());
787             if (networkId.empty()) {
788                 DHLOGE("Can not get device uuid by networkId: %{public}s", GetAnonyString(networkId).c_str());
789                 break;
790             }
791             ComponentManager::GetInstance().TriggerFullCapsSync(networkId);
792             break;
793         }
794         default:
795             DHLOGE("event is undefined, id is %{public}d", eventId);
796             break;
797     }
798 }
799 
GetEventHandler()800 std::shared_ptr<ComponentManager::ComponentManagerEventHandler> ComponentManager::GetEventHandler()
801 {
802     return this->eventHandler_;
803 }
804 
CheckSinkConfigStart(const DHType dhType,bool & enableSink)805 int32_t ComponentManager::CheckSinkConfigStart(const DHType dhType, bool &enableSink)
806 {
807     DHLOGI("CheckSinkConfigStart the dhType: %{public}#X configuration start.", dhType);
808     DHVersion localDhVersion;
809     auto ret = ComponentLoader::GetInstance().GetLocalDHVersion(localDhVersion);
810     if (ret != DH_FWK_SUCCESS) {
811         DHLOGE("GetLocalDHVersion fail.");
812         return ret;
813     }
814     auto iterLocal = localDhVersion.compVersions.find(dhType);
815     if (iterLocal == localDhVersion.compVersions.end()) {
816         DHLOGE("Not find dhType: %{public}#X in local!", dhType);
817         return ERR_DH_FWK_TYPE_NOT_EXIST;
818     }
819     if (!iterLocal->second.haveFeature) {
820         enableSink = true;
821         DHLOGI("Local DhType: %{public}#X is old configuration, need enable sink.", dhType);
822         return DH_FWK_SUCCESS;
823     }
824 
825     if (iterLocal->second.sinkSupportedFeatures.size() > 0) {
826         enableSink = true;
827     }
828     return DH_FWK_SUCCESS;
829 }
830 
CheckDemandStart(const std::string & uuid,const DHType dhType,bool & enableSource)831 int32_t ComponentManager::CheckDemandStart(const std::string &uuid, const DHType dhType, bool &enableSource)
832 {
833     DHLOGI("CheckDemandStart the dhType: %{public}#X configuration start.", dhType);
834     enableSource = false;
835 
836     CompVersion compVersion;
837     auto ret = GetRemoteVerInfo(compVersion, uuid, dhType);
838     if (ret != DH_FWK_SUCCESS) {
839         DHLOGE("GetRemoteVerInfo fail.");
840         return ret;
841     }
842 
843     DHVersion dhVersion;
844     ret = ComponentLoader::GetInstance().GetLocalDHVersion(dhVersion);
845     if (ret != DH_FWK_SUCCESS) {
846         DHLOGE("GetLocalDHVersion fail.");
847         return ret;
848     }
849 
850     auto iterLocal = dhVersion.compVersions.find(dhType);
851     if (iterLocal == dhVersion.compVersions.end()) {
852         DHLOGE("Not find dhType in local: %{public}#X!", dhType);
853         return ERR_DH_FWK_TYPE_NOT_EXIST;
854     }
855 
856     if (!iterLocal->second.haveFeature) {
857         DHLOGI("Local dhType: %{public}#X is old configuration, need enable source", dhType);
858         enableSource = true;
859         return DH_FWK_SUCCESS;
860     }
861     if (iterLocal->second.sourceFeatureFilters.size() == 0) {
862         return DH_FWK_SUCCESS;
863     }
864 
865     enableSource = IsFeatureMatched(iterLocal->second.sourceFeatureFilters, compVersion.sinkSupportedFeatures);
866     return DH_FWK_SUCCESS;
867 }
868 
RegisterDHStatusListener(sptr<IHDSinkStatusListener> listener,int32_t callingUid,int32_t callingPid)869 int32_t ComponentManager::RegisterDHStatusListener(
870     sptr<IHDSinkStatusListener> listener, int32_t callingUid, int32_t callingPid)
871 {
872     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
873     std::vector<DHType> compTypes;
874     ComponentLoader::GetInstance().GetAllCompTypes(compTypes);
875     for (const auto &type : compTypes) {
876         auto &status = dhSinkStatus_[type];
877         DHStatusCtrlKey ctrlKey {
878             .uid = callingUid,
879             .pid = callingPid
880         };
881         auto &listeners = status.listeners;
882         if (listeners.find(ctrlKey) != listeners.end()) {
883             DHLOGE("Repeat call RegisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
884                 ctrlKey.uid, ctrlKey.pid);
885             return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
886         }
887         listeners[ctrlKey] = listener;
888     }
889 
890     return DH_FWK_SUCCESS;
891 }
892 
UnregisterDHStatusListener(sptr<IHDSinkStatusListener> listener,int32_t callingUid,int32_t callingPid)893 int32_t ComponentManager::UnregisterDHStatusListener(
894     sptr<IHDSinkStatusListener> listener, int32_t callingUid, int32_t callingPid)
895 {
896     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
897     std::vector<DHType> compTypes;
898     ComponentLoader::GetInstance().GetAllCompTypes(compTypes);
899     for (const auto &type : compTypes) {
900         auto &status = dhSinkStatus_[type];
901         DHStatusCtrlKey ctrlKey {
902             .uid = callingUid,
903             .pid = callingPid
904         };
905         auto &listeners = status.listeners;
906         auto it = listeners.find(ctrlKey);
907         if (it == listeners.end()) {
908             DHLOGE("Repeat call UnregisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
909                 ctrlKey.uid, ctrlKey.pid);
910             return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
911         }
912         listeners.erase(it);
913     }
914 
915     return DH_FWK_SUCCESS;
916 }
917 
RegisterDHStatusListener(const std::string & networkId,sptr<IHDSourceStatusListener> listener,int32_t callingUid,int32_t callingPid)918 int32_t ComponentManager::RegisterDHStatusListener(
919     const std::string &networkId, sptr<IHDSourceStatusListener> listener, int32_t callingUid, int32_t callingPid)
920 {
921     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
922     std::vector<DHType> compTypes;
923     ComponentLoader::GetInstance().GetAllCompTypes(compTypes);
924     for (const auto &type : compTypes) {
925         auto &status = dhSourceStatus_[type];
926         DHStatusCtrlKey ctrlKey {
927             .uid = callingUid,
928             .pid = callingPid
929         };
930         auto &listeners = status.listeners;
931         if (listeners.find(ctrlKey) != listeners.end()) {
932             DHLOGE("Repeat call RegisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
933                 ctrlKey.uid, ctrlKey.pid);
934             return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
935         }
936         listeners[ctrlKey] = listener;
937     }
938 
939     return DH_FWK_SUCCESS;
940 }
941 
UnregisterDHStatusListener(const std::string & networkId,sptr<IHDSourceStatusListener> listener,int32_t callingUid,int32_t callingPid)942 int32_t ComponentManager::UnregisterDHStatusListener(
943     const std::string &networkId, sptr<IHDSourceStatusListener> listener, int32_t callingUid, int32_t callingPid)
944 {
945     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
946     std::vector<DHType> compTypes;
947     ComponentLoader::GetInstance().GetAllCompTypes(compTypes);
948     for (const auto &type : compTypes) {
949         auto &status = dhSourceStatus_[type];
950         DHStatusCtrlKey ctrlKey {
951             .uid = callingUid,
952             .pid = callingPid
953         };
954         auto &listeners = status.listeners;
955         auto it = listeners.find(ctrlKey);
956         if (it == listeners.end()) {
957             DHLOGE("Repeat call UnregisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
958                 ctrlKey.uid, ctrlKey.pid);
959             return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
960         }
961         listeners.erase(it);
962     }
963 
964     return DH_FWK_SUCCESS;
965 }
966 
EnableSink(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)967 int32_t ComponentManager::EnableSink(const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
968 {
969     sptr<IHDSinkStatusListener> listener;
970     int32_t ret = EnableSinkInternal(dhDescriptor, callingUid, callingPid, listener);
971     if (ret == DH_FWK_SUCCESS) {
972         if (listener) {
973             listener->OnEnable(dhDescriptor);
974             DHLOGI("Callback business sink OnEnable.");
975         }
976     }
977     return ret;
978 }
979 
DisableSink(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)980 int32_t ComponentManager::DisableSink(const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
981 {
982     sptr<IHDSinkStatusListener> listener;
983     int32_t ret = DisableSinkInternal(dhDescriptor, callingUid, callingPid, listener);
984     if (ret == DH_FWK_SUCCESS) {
985         if (listener) {
986             listener->OnDisable(dhDescriptor);
987             DHLOGI("Callback business sink OnDisable.");
988         }
989     }
990     return ret;
991 }
992 
EnableSource(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)993 int32_t ComponentManager::EnableSource(const std::string &networkId,
994     const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
995 {
996     sptr<IHDSourceStatusListener> listener;
997     int32_t ret = EnableSourceInternal(networkId, dhDescriptor, callingUid, callingPid, listener);
998     if (ret == DH_FWK_SUCCESS) {
999         if (listener) {
1000             listener->OnEnable(networkId, dhDescriptor);
1001             DHLOGI("Callback business source OnEnable.");
1002         }
1003     }
1004     return ret;
1005 }
1006 
DisableSource(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)1007 int32_t ComponentManager::DisableSource(const std::string &networkId,
1008     const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
1009 {
1010     sptr<IHDSourceStatusListener> listener;
1011     int32_t ret = DisableSourceInternal(networkId, dhDescriptor, callingUid, callingPid, listener);
1012     if (ret == DH_FWK_SUCCESS) {
1013         if (listener) {
1014             listener->OnDisable(networkId, dhDescriptor);
1015             DHLOGI("Callback business source OnDisable.");
1016         }
1017     }
1018     return ret;
1019 }
1020 
ForceDisableSink(const DHDescriptor & dhDescriptor)1021 int32_t ComponentManager::ForceDisableSink(const DHDescriptor &dhDescriptor)
1022 {
1023     std::vector<sptr<IHDSinkStatusListener>> listeners;
1024     int32_t ret = ForceDisableSinkInternal(dhDescriptor, listeners);
1025     if (ret == DH_FWK_SUCCESS) {
1026         for (auto listener : listeners) {
1027             listener->OnDisable(dhDescriptor);
1028             DHLOGI("Callback business sink OnDisable.");
1029         }
1030     }
1031     return ret;
1032 }
1033 
ForceDisableSource(const std::string & networkId,const DHDescriptor & dhDescriptor)1034 int32_t ComponentManager::ForceDisableSource(const std::string &networkId, const DHDescriptor &dhDescriptor)
1035 {
1036     if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1037         DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1038         return ERR_DH_FWK_TYPE_NOT_EXIST;
1039     }
1040     std::vector<sptr<IHDSourceStatusListener>> listeners;
1041     int32_t ret = ForceDisableSourceInternal(networkId, dhDescriptor, listeners);
1042     if (ret == DH_FWK_SUCCESS) {
1043         for (auto listener : listeners) {
1044             listener->OnDisable(networkId, dhDescriptor);
1045             DHLOGI("Callback business source OnDisable.");
1046         }
1047     }
1048     return ret;
1049 }
1050 
CheckIdenticalAccount(const std::string & networkId,const std::string & uuid,const DHDescriptor & dhDescriptor)1051 int32_t ComponentManager::CheckIdenticalAccount(const std::string &networkId,
1052     const std::string &uuid, const DHDescriptor &dhDescriptor)
1053 {
1054     EnableParam param;
1055     auto ret = GetEnableParam(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType, param);
1056     if (ret != DH_FWK_SUCCESS) {
1057         DHLOGE("GetEnableParam failed, uuid = %{public}s, dhId = %{public}s, errCode = %{public}d",
1058             GetAnonyString(uuid).c_str(), GetAnonyString(dhDescriptor.id).c_str(), ret);
1059         if (ComponentManager::GetInstance().RetryGetEnableParam(
1060             networkId, uuid, dhDescriptor.id, dhDescriptor.dhType, param) != DH_FWK_SUCCESS) {
1061             return ret;
1062         }
1063     }
1064     ret = CheckSubtypeResource(param.subtype, networkId);
1065     if (ret != DH_FWK_SUCCESS) {
1066         DHLOGE("CheckSubtypeResource failed, ret = %{public}d.", ret);
1067         return ret;
1068     }
1069     return DH_FWK_SUCCESS;
1070 }
1071 
GetRemoteVerInfo(CompVersion & compVersion,const std::string & uuid,DHType dhType)1072 int32_t ComponentManager::GetRemoteVerInfo(CompVersion &compVersion, const std::string &uuid, DHType dhType)
1073 {
1074     MetaCapInfoMap metaInfoMap;
1075     MetaInfoManager::GetInstance()->GetMetaDataByDHType(dhType, metaInfoMap);
1076     for (const auto &metaInfo : metaInfoMap) {
1077         if (DHContext::GetInstance().GetUUIDByDeviceId(metaInfo.second->GetDeviceId()) == uuid) {
1078             compVersion = metaInfo.second->GetCompVersion();
1079             return DH_FWK_SUCCESS;
1080         }
1081     }
1082     DHLOGE("The metaInfo corresponding to uuid was not found, uuid =%{public}s, dhType = %{public}#X.",
1083         GetAnonyString(uuid).c_str(), dhType);
1084     return ERR_DH_FWK_COMPONENT_COMPVERSION_NOT_FOUND;
1085 }
1086 
IsFeatureMatched(const std::vector<std::string> & sourceFeatureFilters,const std::vector<std::string> & sinkSupportedFeatures)1087 bool ComponentManager::IsFeatureMatched(const std::vector<std::string> &sourceFeatureFilters,
1088     const std::vector<std::string> &sinkSupportedFeatures)
1089 {
1090     for (const auto &filter : sourceFeatureFilters) {
1091         for (const auto &feature : sinkSupportedFeatures) {
1092             if (feature == filter) {
1093                 return true;
1094             }
1095         }
1096     }
1097     DHLOGE("The sourcefeature and the sinkfeature do not match.");
1098     return false;
1099 }
1100 
EnableSinkInternal(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSinkStatusListener> & listener)1101 int32_t ComponentManager::EnableSinkInternal(const DHDescriptor &dhDescriptor,
1102     int32_t callingUid, int32_t callingPid, sptr<IHDSinkStatusListener> &listener)
1103 {
1104     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1105 
1106     // Check if the input parameters and device type support it
1107     if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1108         DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1109         return ERR_DH_FWK_TYPE_NOT_EXIST;
1110     }
1111 
1112     auto &status = dhSinkStatus_[dhDescriptor.dhType];
1113     auto &enableInfo = status.enableInfos[dhDescriptor.id];
1114 
1115     // Check if the business is being called repeatedly
1116     DHStatusCtrlKey ctrlKey {
1117         .uid = callingUid,
1118         .pid = callingPid
1119     };
1120     auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1121     if (statusCtrl.enableState == EnableState::ENABLED) {
1122         DHLOGE("Repeat call EnableSink, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1123         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1124     }
1125 
1126     // Get business enable status listener
1127     auto itrListener = status.listeners.find(ctrlKey);
1128     if (itrListener != status.listeners.end()) {
1129         listener = itrListener->second;
1130     }
1131 
1132     // Check reference count
1133     if (enableInfo.refEnable || status.refLoad) {
1134         // Change status, we won't call back directly here because there is a lock
1135         statusCtrl.enableState = EnableState::ENABLED;
1136         enableInfo.refEnable++;
1137         status.refLoad++;
1138         return DH_FWK_SUCCESS;
1139     }
1140 
1141     // Start enabling hardware sink
1142     auto ret = InitCompSink(dhDescriptor.dhType);
1143     if (ret != DH_FWK_SUCCESS) {
1144         DHLOGE("InitCompSink failed, ret = %{public}d.", ret);
1145         return ret;
1146     }
1147     std::unordered_map<DHType, std::shared_future<int32_t>> sinkResult;
1148     ret = StartSink(dhDescriptor.dhType, sinkResult);
1149     if (ret != DH_FWK_SUCCESS) {
1150         DHLOGE("StartSink failed");
1151         return ret;
1152     }
1153     if (!WaitForResult(Action::START_SINK, sinkResult)) {
1154         DHLOGE("StartSink failed, some virtual components maybe cannot work, but want to continue!");
1155         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1156             "dhfwk start sink failed.");
1157         UninitCompSink(dhDescriptor.dhType);
1158         return ERR_DH_FWK_COMPONENT_ENABLE_TIMEOUT;
1159     }
1160     // Change status, we won't call back directly here because there is a lock
1161     statusCtrl.enableState = EnableState::ENABLED;
1162     enableInfo.refEnable = 1;
1163     status.refLoad = 1;
1164     return DH_FWK_SUCCESS;
1165 }
1166 
DisableSinkInternal(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSinkStatusListener> & listener)1167 int32_t ComponentManager::DisableSinkInternal(const DHDescriptor &dhDescriptor,
1168     int32_t callingUid, int32_t callingPid, sptr<IHDSinkStatusListener> &listener)
1169 {
1170     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1171 
1172     // Check if the input parameters and device type support it
1173     if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1174         DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1175         return ERR_DH_FWK_TYPE_NOT_EXIST;
1176     }
1177 
1178     auto &status = dhSinkStatus_[dhDescriptor.dhType];
1179     auto &enableInfo = status.enableInfos[dhDescriptor.id];
1180 
1181     // Check if the business is being called repeatedly
1182     DHStatusCtrlKey ctrlKey {
1183         .uid = callingUid,
1184         .pid = callingPid
1185     };
1186     auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1187     if (statusCtrl.enableState == EnableState::DISABLED) {
1188         DHLOGE("Repeat call DisableSink, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1189         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1190     }
1191 
1192     // Get business enable status listener
1193     auto itrListener = status.listeners.find(ctrlKey);
1194     if (itrListener != status.listeners.end()) {
1195         listener = itrListener->second;
1196     }
1197 
1198     // Check reference count
1199     if (enableInfo.refEnable > 1 || status.refLoad > 1) {
1200         // Change status, we won't call back directly here because there is a lock
1201         statusCtrl.enableState = EnableState::DISABLED;
1202         enableInfo.refEnable--;
1203         status.refLoad--;
1204         return DH_FWK_SUCCESS;
1205     }
1206 
1207     // Start disabling hardware sink
1208     std::unordered_map<DHType, std::shared_future<int32_t>> sinkResult;
1209     auto ret = StopSink(dhDescriptor.dhType, sinkResult);
1210     if (ret != DH_FWK_SUCCESS) {
1211         DHLOGE("StopSink failed!");
1212         return ret;
1213     }
1214     if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
1215         DHLOGE("StopSink failed, but want to continue!");
1216         return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1217     }
1218     ret = UninitCompSink(dhDescriptor.dhType);
1219     if (ret != DH_FWK_SUCCESS) {
1220         DHLOGE("UninitCompSink failed, ret = %{public}d.", ret);
1221         return ret;
1222     }
1223     // Change status, we won't call back directly here because there is a lock
1224     statusCtrl.enableState = EnableState::DISABLED;
1225     enableInfo.refEnable = 0;
1226     status.refLoad = 0;
1227     return DH_FWK_SUCCESS;
1228 }
1229 
EnableSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSourceStatusListener> & listener)1230 int32_t ComponentManager::EnableSourceInternal(const std::string &networkId,
1231     const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid, sptr<IHDSourceStatusListener> &listener)
1232 {
1233     // Check if the input parameters and device type support it
1234     if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1235         DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1236         return ERR_DH_FWK_TYPE_NOT_EXIST;
1237     }
1238 
1239     DHStatusSourceEnableInfoKey enableInfoKey { .networkId = networkId, .dhId = dhDescriptor.id };
1240     DHStatusCtrlKey ctrlKey { .uid = callingUid, .pid = callingPid };
1241     auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
1242 
1243     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1244 
1245     auto &status = dhSourceStatus_[dhDescriptor.dhType];
1246     auto &enableInfo = status.enableInfos[enableInfoKey];
1247 
1248     // Check if the business is being called repeatedly
1249     auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1250     if (statusCtrl.enableState == EnableState::ENABLED) {
1251         DHLOGE("Repeat call EnableSource, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1252         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1253     }
1254 
1255     // Get business enable status listener
1256     auto itrListener = status.listeners.find(ctrlKey);
1257     if (itrListener != status.listeners.end()) {
1258         listener = itrListener->second;
1259     }
1260 
1261     // Check enable reference count
1262     if (enableInfo.refEnable) {
1263         // Change status, we won't call back directly here because there is a lock
1264         statusCtrl.enableState = EnableState::ENABLED;
1265         enableInfo.refEnable++;
1266         status.refLoad++;
1267         return DH_FWK_SUCCESS;
1268     }
1269 
1270     // Check load reference count
1271     if (status.refLoad) {
1272         auto ret = Enable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType,
1273             (callingUid != 0) || (callingPid != 0));
1274         if (ret != DH_FWK_SUCCESS) {
1275             DHLOGE("Enable failed, ret = %{public}d.", ret);
1276             return ret;
1277         }
1278         // Change status, we won't call back directly here because there is a lock
1279         statusCtrl.enableState = EnableState::ENABLED;
1280         enableInfo.refEnable++;
1281         status.refLoad++;
1282         return DH_FWK_SUCCESS;
1283     }
1284 
1285     auto ret = RealEnableSource(networkId, uuid, dhDescriptor, statusCtrl, enableInfo, status,
1286         (callingUid != 0) || (callingPid != 0));
1287     if (ret != DH_FWK_SUCCESS) {
1288         DHLOGE("RealEnableSource failed, ret = %{public}d.", ret);
1289         return ret;
1290     }
1291 
1292     return DH_FWK_SUCCESS;
1293 }
1294 
DisableSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSourceStatusListener> & listener)1295 int32_t ComponentManager::DisableSourceInternal(const std::string &networkId,
1296     const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid, sptr<IHDSourceStatusListener> &listener)
1297 {
1298     // Check if the input parameters and device type support it
1299     if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1300         DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1301         return ERR_DH_FWK_TYPE_NOT_EXIST;
1302     }
1303 
1304     DHStatusSourceEnableInfoKey enableInfoKey {
1305         .networkId = networkId,
1306         .dhId = dhDescriptor.id
1307     };
1308     DHStatusCtrlKey ctrlKey {
1309         .uid = callingUid,
1310         .pid = callingPid
1311     };
1312     auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
1313 
1314     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1315 
1316     auto &status = dhSourceStatus_[dhDescriptor.dhType];
1317     auto &enableInfo = status.enableInfos[enableInfoKey];
1318 
1319     // Check if the business is being called repeatedly
1320     auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1321     if (statusCtrl.enableState == EnableState::DISABLED) {
1322         DHLOGE("Repeat call DisableSource, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1323         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1324     }
1325 
1326     // Get business enable status listener
1327     auto itrListener = status.listeners.find(ctrlKey);
1328     if (itrListener != status.listeners.end()) {
1329         listener = itrListener->second;
1330     }
1331 
1332     // Check enable reference count
1333     if (enableInfo.refEnable > 1) {
1334         // Change status, we won't call back directly here because there is a lock
1335         statusCtrl.enableState = EnableState::DISABLED;
1336         enableInfo.refEnable--;
1337         status.refLoad--;
1338         return DH_FWK_SUCCESS;
1339     }
1340 
1341     // Check load reference count
1342     if (status.refLoad > 1) {
1343         auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType);
1344         if (ret != DH_FWK_SUCCESS) {
1345             DHLOGE("Disable failed, ret = %{public}d.", ret);
1346             return ret;
1347         }
1348         // Change status, we won't call back directly here because there is a lock
1349         statusCtrl.enableState = EnableState::DISABLED;
1350         enableInfo.refEnable--;
1351         status.refLoad--;
1352         return DH_FWK_SUCCESS;
1353     }
1354 
1355     auto ret = RealDisableSource(networkId, uuid, dhDescriptor, statusCtrl, enableInfo, status);
1356     if (ret != DH_FWK_SUCCESS) {
1357         DHLOGE("RealDisableSource failed, ret = %{public}d.", ret);
1358         return ret;
1359     }
1360 
1361     return DH_FWK_SUCCESS;
1362 }
1363 
ForceDisableSinkInternal(const DHDescriptor & dhDescriptor,std::vector<sptr<IHDSinkStatusListener>> & listeners)1364 int32_t ComponentManager::ForceDisableSinkInternal(
1365     const DHDescriptor &dhDescriptor, std::vector<sptr<IHDSinkStatusListener>> &listeners)
1366 {
1367     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1368 
1369     // Check if the input parameters and device type support it
1370     if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1371         DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1372         return ERR_DH_FWK_TYPE_NOT_EXIST;
1373     }
1374 
1375     auto &status = dhSinkStatus_[dhDescriptor.dhType];
1376     auto itEnableInfo = status.enableInfos.find(dhDescriptor.id);
1377     if (itEnableInfo == status.enableInfos.end()) {
1378         DHLOGE("Repeat call ForceDisableSink, dhType = %{public}u, id = %{public}s.",
1379             dhDescriptor.dhType, GetAnonyString(dhDescriptor.id).c_str());
1380         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1381     }
1382     auto &enableInfo = itEnableInfo->second;
1383 
1384     // Collect listeners and reduce the load count
1385     for (auto &item : enableInfo.dhStatusCtrl) {
1386         if (item.second.enableState != EnableState::DISABLED) {
1387             auto it = status.listeners.find(item.first);
1388             if (it != status.listeners.end()) {
1389                 auto listener = it->second;
1390                 listeners.push_back(listener);
1391             }
1392         }
1393     }
1394     status.refLoad -= enableInfo.refEnable;
1395     status.enableInfos.erase(itEnableInfo);
1396     if (status.refLoad > 0) {
1397         return DH_FWK_SUCCESS;
1398     }
1399 
1400     // Unload component
1401     std::unordered_map<DHType, std::shared_future<int32_t>> sinkResult;
1402     auto ret = StopSink(dhDescriptor.dhType, sinkResult);
1403     if (ret != DH_FWK_SUCCESS) {
1404         DHLOGE("StopSink failed!");
1405         return ret;
1406     }
1407     if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
1408         DHLOGE("StopSink failed, but want to continue!");
1409         return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1410     }
1411     ret = UninitCompSink(dhDescriptor.dhType);
1412     if (ret != DH_FWK_SUCCESS) {
1413         DHLOGE("UninitCompSink failed, ret = %{public}d.", ret);
1414         return ret;
1415     }
1416     return DH_FWK_SUCCESS;
1417 }
1418 
ForceDisableSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,std::vector<sptr<IHDSourceStatusListener>> & listeners)1419 int32_t ComponentManager::ForceDisableSourceInternal(const std::string &networkId,
1420     const DHDescriptor &dhDescriptor, std::vector<sptr<IHDSourceStatusListener>> &listeners)
1421 {
1422     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1423     DHStatusSourceEnableInfoKey enableInfoKey { networkId, dhDescriptor.id };
1424     auto &status = dhSourceStatus_[dhDescriptor.dhType];
1425     auto itEnableInfo = status.enableInfos.find(enableInfoKey);
1426     if (itEnableInfo == status.enableInfos.end()) {
1427         DHLOGE("Repeat call ForceDisableSource, networkId = %{public}s, dhType = %{public}u, id = %{public}s.",
1428             GetAnonyString(networkId).c_str(), dhDescriptor.dhType, GetAnonyString(dhDescriptor.id).c_str());
1429         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1430     }
1431     auto &enableInfo = itEnableInfo->second;
1432 
1433     // First, disable the hardware
1434     auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
1435     auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType);
1436     if (ret != DH_FWK_SUCCESS) {
1437         DHLOGE("Disable failed, ret = %{public}d.", ret);
1438         return ret;
1439     }
1440 
1441     // Then collect listeners and reduce the load count
1442     for (auto &item : enableInfo.dhStatusCtrl) {
1443         if (item.second.enableState != EnableState::DISABLED) {
1444             auto it = status.listeners.find(item.first);
1445             if (it != status.listeners.end()) {
1446                 listeners.push_back(it->second);
1447             }
1448         }
1449     }
1450     status.refLoad -= enableInfo.refEnable;
1451     status.enableInfos.erase(itEnableInfo);
1452     if (status.refLoad > 0) {
1453         return DH_FWK_SUCCESS;
1454     }
1455 
1456     // Unload component
1457     std::unordered_map<DHType, std::shared_future<int32_t>> sourceResult;
1458     ret = StopSource(dhDescriptor.dhType, sourceResult);
1459     if (ret != DH_FWK_SUCCESS) {
1460         DHLOGE("StopSource failed");
1461         return ret;
1462     }
1463     if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
1464         DHLOGE("StopSource timeout!");
1465         return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1466     }
1467     ret = UninitCompSource(dhDescriptor.dhType);
1468     if (ret != DH_FWK_SUCCESS) {
1469         DHLOGE("UninitCompSource failed, ret = %{public}d.", ret);
1470         return ret;
1471     }
1472     return DH_FWK_SUCCESS;
1473 }
1474 
RealEnableSource(const std::string & networkId,const std::string & uuid,const DHDescriptor & dhDescriptor,DHStatusCtrl & statusCtrl,DHStatusEnableInfo & enableInfo,DHSourceStatus & status,bool isActive)1475 int32_t ComponentManager::RealEnableSource(const std::string &networkId, const std::string &uuid,
1476     const DHDescriptor &dhDescriptor, DHStatusCtrl &statusCtrl,
1477     DHStatusEnableInfo &enableInfo, DHSourceStatus &status, bool isActive)
1478 {
1479     auto ret = InitCompSource(dhDescriptor.dhType);
1480     if (ret != DH_FWK_SUCCESS) {
1481         DHLOGE("InitCompSource failed, ret = %{public}d.", ret);
1482         return ret;
1483     }
1484     std::unordered_map<DHType, std::shared_future<int32_t>> sourceResult;
1485     ret = StartSource(dhDescriptor.dhType, sourceResult);
1486     if (ret != DH_FWK_SUCCESS) {
1487         DHLOGE("StartSource failed");
1488         return ret;
1489     }
1490     if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
1491         DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue!");
1492         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1493             "dhfwk start source failed.");
1494         UninitCompSource(dhDescriptor.dhType);
1495         return ERR_DH_FWK_COMPONENT_ENABLE_TIMEOUT;
1496     }
1497     ret = Enable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType, isActive);
1498     if (ret != DH_FWK_SUCCESS) {
1499         DHLOGE("Enable failed, ret = %{public}d.", ret);
1500         std::unordered_map<DHType, std::shared_future<int32_t>> futureResult;
1501         StopSource(dhDescriptor.dhType, futureResult);
1502         UninitCompSource(dhDescriptor.dhType);
1503         return ret;
1504     }
1505     // Change status, we won't call back directly here because there is a lock
1506     statusCtrl.enableState = EnableState::ENABLED;
1507     enableInfo.refEnable = 1;
1508     status.refLoad = 1;
1509     return ret;
1510 }
1511 
RealDisableSource(const std::string & networkId,const std::string & uuid,const DHDescriptor & dhDescriptor,DHStatusCtrl & statusCtrl,DHStatusEnableInfo & enableInfo,DHSourceStatus & status)1512 int32_t ComponentManager::RealDisableSource(const std::string &networkId, const std::string &uuid,
1513     const DHDescriptor &dhDescriptor, DHStatusCtrl &statusCtrl,
1514     DHStatusEnableInfo &enableInfo, DHSourceStatus &status)
1515 {
1516     auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType);
1517     if (ret != DH_FWK_SUCCESS) {
1518         DHLOGE("Disable failed, ret = %{public}d.", ret);
1519         return ret;
1520     }
1521     std::unordered_map<DHType, std::shared_future<int32_t>> sourceResult;
1522     ret = StopSource(dhDescriptor.dhType, sourceResult);
1523     if (ret != DH_FWK_SUCCESS) {
1524         DHLOGE("StopSource failed");
1525         return ret;
1526     }
1527     if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
1528         DHLOGE("StopSource timeout!");
1529         return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1530     }
1531     ret = UninitCompSource(dhDescriptor.dhType);
1532     if (ret != DH_FWK_SUCCESS) {
1533         DHLOGE("UninitCompSource failed, ret = %{public}d.", ret);
1534         return ret;
1535     }
1536     // Change status, we won't call back directly here because there is a lock
1537     statusCtrl.enableState = EnableState::DISABLED;
1538     enableInfo.refEnable = 0;
1539     status.refLoad = 0;
1540     return DH_FWK_SUCCESS;
1541 }
1542 
ResetSinkEnableStatus(DHType dhType)1543 void ComponentManager::ResetSinkEnableStatus(DHType dhType)
1544 {
1545     DHLOGI("ResetSinkEnableStatus begin, dhType = %{public}#X.", dhType);
1546     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1547     auto ret = UninitCompSink(dhType);
1548     if (ret != DH_FWK_SUCCESS) {
1549         DHLOGE("UninitCompSink failed, ret = %{public}d, but want to continue!", ret);
1550     }
1551     auto itSinkStatus = dhSinkStatus_.find(dhType);
1552     if (itSinkStatus == dhSinkStatus_.end()) {
1553         DHLOGI("No need to reset the auto-enable-sink of this type, dhType: %{public}#X.", dhType);
1554         return;
1555     }
1556     auto &sinkStatus = itSinkStatus->second;
1557     sinkStatus.refLoad = 0;
1558     for (auto &itEnableInfo : sinkStatus.enableInfos) {
1559         auto &enableInfoKey = itEnableInfo.first;
1560         auto &enableInfo = itEnableInfo.second;
1561         enableInfo.refEnable = 0;
1562         for (auto &itStatusCtrl : enableInfo.dhStatusCtrl) {
1563             auto &statusCtrlKey = itStatusCtrl.first;
1564             auto &statusCtrl = itStatusCtrl.second;
1565             if (statusCtrlKey.uid == 0 && statusCtrlKey.pid == 0) {
1566                 statusCtrl.enableState = EnableState::DISABLED;
1567                 DHLOGI("reset the auto-enable-sink, dhId = %{public}s, dhType: %{public}#X.",
1568                     GetAnonyString(enableInfoKey).c_str(), dhType);
1569             }
1570         }
1571     }
1572     DHLOGI("ResetSinkEnableStatus end, dhType = %{public}#X.", dhType);
1573 }
1574 
ResetSourceEnableStatus(DHType dhType)1575 void ComponentManager::ResetSourceEnableStatus(DHType dhType)
1576 {
1577     DHLOGI("ResetSourceEnableStatus begin, dhType = %{public}#X.", dhType);
1578     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1579     auto ret = UninitCompSource(dhType);
1580     if (ret != DH_FWK_SUCCESS) {
1581         DHLOGE("UninitCompSource failed, ret = %{public}d, but want to continue!", ret);
1582     }
1583     auto itSourceStatus = dhSourceStatus_.find(dhType);
1584     if (itSourceStatus == dhSourceStatus_.end()) {
1585         DHLOGI("No need to reset the auto-enable-source of this type, dhType: %{public}#X.", dhType);
1586         return;
1587     }
1588     auto &sourcekStatus = itSourceStatus->second;
1589     sourcekStatus.refLoad = 0;
1590     for (auto &itEnableInfo : sourcekStatus.enableInfos) {
1591         auto &enableInfoKey = itEnableInfo.first;
1592         auto &enableInfo = itEnableInfo.second;
1593         enableInfo.refEnable = 0;
1594         for (auto &itStatusCtrl : enableInfo.dhStatusCtrl) {
1595             auto &statusCtrlKey = itStatusCtrl.first;
1596             auto &statusCtrl = itStatusCtrl.second;
1597             if (statusCtrlKey.uid == 0 && statusCtrlKey.pid == 0) {
1598                 statusCtrl.enableState = EnableState::DISABLED;
1599                 DHLOGI("reset the auto-enable-source, networkId = %{public}s, dhId = %{public}s, dhType: %{public}#X.",
1600                     GetAnonyString(enableInfoKey.networkId).c_str(),
1601                     GetAnonyString(enableInfoKey.dhId).c_str(), dhType);
1602             }
1603         }
1604     }
1605     DHLOGI("ResetSourceEnableStatus end, dhType = %{public}#X.", dhType);
1606 }
1607 
RecoverAutoEnableSink(DHType dhType)1608 void ComponentManager::RecoverAutoEnableSink(DHType dhType)
1609 {
1610     DHLOGI("RecoverAutoEnableSink begin, dhType = %{public}#X.", dhType);
1611     DeviceInfo localDeviceInfo = GetLocalDeviceInfo();
1612     std::vector<std::pair<std::string, DHType>> localMetaInfos;
1613     std::vector<std::shared_ptr<MetaCapabilityInfo>> metaCapInfos;
1614     MetaInfoManager::GetInstance()->GetMetaCapInfosByUdidHash(localDeviceInfo.udidHash, metaCapInfos);
1615     std::for_each(metaCapInfos.begin(), metaCapInfos.end(), [&](std::shared_ptr<MetaCapabilityInfo> localMetaInfo) {
1616         if (localMetaInfo != nullptr && localMetaInfo->GetDHType() == dhType) {
1617             localMetaInfos.push_back({localMetaInfo->GetDHId(), localMetaInfo->GetDHType()});
1618         }
1619     });
1620     if (localMetaInfos.empty()) {
1621         DHLOGE("No need to recover auto enable sink, dhType = %{public}#X.", dhType);
1622         return;
1623     }
1624     for (const auto &localInfo : localMetaInfos) {
1625         TaskParam taskParam = {
1626             .networkId = localDeviceInfo.networkId,
1627             .uuid = localDeviceInfo.uuid,
1628             .udid = localDeviceInfo.udid,
1629             .dhId = localInfo.first,
1630             .dhType = localInfo.second
1631         };
1632         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
1633         TaskExecutor::GetInstance().PushTask(task);
1634     }
1635     DHLOGI("RecoverAutoEnableSink end, dhType = %{public}#X.", dhType);
1636 }
1637 
RecoverAutoEnableSource(DHType dhType)1638 void ComponentManager::RecoverAutoEnableSource(DHType dhType)
1639 {
1640     DHLOGI("RecoverAutoEnableSource begin, dhType = %{public}#X.", dhType);
1641     MetaCapInfoMap metaInfoMap;
1642     MetaInfoManager::GetInstance()->GetMetaDataByDHType(dhType, metaInfoMap);
1643     for (const auto &metaInfo : metaInfoMap) {
1644         std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(metaInfo.second->GetDeviceId());
1645         if (uuid.empty()) {
1646             DHLOGE("Can not find uuid by capability deviceId: %{public}s",
1647                 GetAnonyString(metaInfo.second->GetDeviceId()).c_str());
1648             continue;
1649         }
1650 
1651         std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
1652         if (networkId.empty()) {
1653             DHLOGI("Can not find network id by uuid: %{public}s", GetAnonyString(uuid).c_str());
1654             continue;
1655         }
1656 
1657         TaskParam taskParam = {
1658             .networkId = networkId,
1659             .uuid = uuid,
1660             .dhId = metaInfo.second->GetDHId(),
1661             .dhType = metaInfo.second->GetDHType()
1662         };
1663         auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
1664         TaskExecutor::GetInstance().PushTask(task);
1665     }
1666     DHLOGI("RecoverAutoEnableSource end, dhType = %{public}#X.", dhType);
1667 }
1668 
RecoverActiveEnableSink(DHType dhType)1669 void ComponentManager::RecoverActiveEnableSink(DHType dhType)
1670 {
1671     DHLOGI("RecoverActiveEnableSink begin, dhType = %{public}#X.", dhType);
1672     std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1673     auto itSinkStatus = dhSinkStatus_.find(dhType);
1674     if (itSinkStatus == dhSinkStatus_.end()) {
1675         DHLOGE("No need to recover active enable sink, dhType = %{public}#X.", dhType);
1676         return;
1677     }
1678     auto &sinkStatus = itSinkStatus->second;
1679     for (auto &itEnableInfo : sinkStatus.enableInfos) {
1680         auto &enableInfoKey = itEnableInfo.first;
1681         auto &enableInfo = itEnableInfo.second;
1682         for (auto &itStatusCtrl : enableInfo.dhStatusCtrl) {
1683             auto &statusCtrlKey = itStatusCtrl.first;
1684             auto &statusCtrl = itStatusCtrl.second;
1685             if ((statusCtrlKey.uid != 0 || statusCtrlKey.pid != 0)
1686                 && statusCtrl.enableState == EnableState::ENABLED) {
1687                 statusCtrl.enableState = EnableState::DISABLED;
1688                 TaskParam taskParam = {
1689                     .dhId = enableInfoKey,
1690                     .dhType = dhType,
1691                     .effectSink = true,
1692                     .effectSource = false,
1693                     .callingUid = statusCtrlKey.uid,
1694                     .callingPid = statusCtrlKey.pid
1695                 };
1696                 auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
1697                 TaskExecutor::GetInstance().PushTask(task);
1698                 DHLOGI("Create enable task for recover active-enable-sink, dhId = %{public}s, dhType = %{public}#X.",
1699                     GetAnonyString(enableInfoKey).c_str(), dhType);
1700             }
1701         }
1702     }
1703     DHLOGI("RecoverActiveEnableSink end, dhType = %{public}#X.", dhType);
1704 }
1705 
RecoverActiveEnableSource(DHType dhType)1706 void ComponentManager::RecoverActiveEnableSource(DHType dhType)
1707 {
1708     DHLOGI("RecoverActiveEnableSource begin, dhType = %{public}#X.", dhType);
1709     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1710     auto itSourceStatus = dhSourceStatus_.find(dhType);
1711     if (itSourceStatus == dhSourceStatus_.end()) {
1712         DHLOGE("No need to recover active enable source, dhType = %{public}#X.", dhType);
1713         return;
1714     }
1715     auto &sourcekStatus = itSourceStatus->second;
1716     for (auto &itEnableInfo : sourcekStatus.enableInfos) {
1717         auto &enableInfoKey = itEnableInfo.first;
1718         auto &enableInfo = itEnableInfo.second;
1719         for (auto &itStatusCtrl : enableInfo.dhStatusCtrl) {
1720             auto &statusCtrlKey = itStatusCtrl.first;
1721             auto &statusCtrl = itStatusCtrl.second;
1722             if ((statusCtrlKey.uid != 0 || statusCtrlKey.pid != 0)
1723                 && statusCtrl.enableState == EnableState::ENABLED) {
1724                 statusCtrl.enableState = EnableState::DISABLED;
1725                 TaskParam taskParam = {
1726                     .networkId = enableInfoKey.networkId,
1727                     .dhId = enableInfoKey.dhId,
1728                     .dhType = dhType,
1729                     .effectSink = false,
1730                     .effectSource = true,
1731                     .callingUid = statusCtrlKey.uid,
1732                     .callingPid = statusCtrlKey.pid
1733                 };
1734                 auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
1735                 TaskExecutor::GetInstance().PushTask(task);
1736                 DHLOGI("Create enable task for recover active-enable-sink, "
1737                     "networkId = %{public}s, dhId = %{public}s, dhType = %{public}#X.",
1738                     GetAnonyString(enableInfoKey.networkId).c_str(),
1739                     GetAnonyString(enableInfoKey.dhId).c_str(), dhType);
1740             }
1741         }
1742     }
1743     DHLOGI("RecoverActiveEnableSource end, dhType = %{public}#X.", dhType);
1744 }
1745 
InitCompSource(DHType dhType)1746 int32_t ComponentManager::InitCompSource(DHType dhType)
1747 {
1748     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
1749     IDistributedHardwareSource *sourcePtr = nullptr;
1750     auto ret = ComponentLoader::GetInstance().GetSource(dhType, sourcePtr);
1751     if (ret != DH_FWK_SUCCESS) {
1752         DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1753         return ret;
1754     }
1755     if (sourcePtr == nullptr) {
1756         DHLOGE("sourcePtr is null, compType = %{public}#X.", dhType);
1757         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
1758     }
1759     compSource_.insert(std::make_pair(dhType, sourcePtr));
1760     auto saId = ComponentLoader::GetInstance().GetSourceSaId(dhType);
1761     if (saId != INVALID_SA_ID) {
1762         compSrcSaId_.insert(std::make_pair(dhType, saId));
1763         if (compMonitorPtr_ == nullptr) {
1764             DHLOGE("compMonitorPtr_ is null.");
1765             return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
1766         }
1767         compMonitorPtr_->AddSAMonitor(saId);
1768     } else {
1769         DHLOGE("GetSourceSaId return INVALID_SA_ID, compType = %{public}#X.", dhType);
1770     }
1771     sourcePtr->RegisterDistributedHardwareStateListener(dhStateListener_);
1772     sourcePtr->RegisterDataSyncTriggerListener(dataSyncTriggerListener_);
1773     return DH_FWK_SUCCESS;
1774 }
1775 
UninitCompSource(DHType dhType)1776 int32_t ComponentManager::UninitCompSource(DHType dhType)
1777 {
1778     std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
1779     IDistributedHardwareSource *sourcePtr = nullptr;
1780     auto ret = ComponentLoader::GetInstance().GetSource(dhType, sourcePtr);
1781     if (ret != DH_FWK_SUCCESS) {
1782         DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1783         return ret;
1784     }
1785     if (sourcePtr == nullptr) {
1786         DHLOGE("sourcePtr is null, compType = %{public}#X.", dhType);
1787         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
1788     }
1789     sourcePtr->UnregisterDataSyncTriggerListener();
1790     sourcePtr->UnregisterDistributedHardwareStateListener();
1791     auto it = compSrcSaId_.find(dhType);
1792     if (it != compSrcSaId_.end()) {
1793         if (compMonitorPtr_ == nullptr) {
1794             DHLOGE("compMonitorPtr_ is null.");
1795             return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
1796         }
1797         compMonitorPtr_->RemoveSAMonitor(it->second);
1798         compSrcSaId_.erase(it);
1799     }
1800     ret = ComponentLoader::GetInstance().ReleaseSource(dhType);
1801     if (ret != DH_FWK_SUCCESS) {
1802         DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1803         return ret;
1804     }
1805     compSource_.erase(dhType);
1806     return DH_FWK_SUCCESS;
1807 }
1808 
InitCompSink(DHType dhType)1809 int32_t ComponentManager::InitCompSink(DHType dhType)
1810 {
1811     std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
1812     IDistributedHardwareSink *sinkPtr = nullptr;
1813     auto ret = ComponentLoader::GetInstance().GetSink(dhType, sinkPtr);
1814     if (ret != DH_FWK_SUCCESS) {
1815         DHLOGE("GetSink failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1816         return ret;
1817     }
1818     if (sinkPtr == nullptr) {
1819         DHLOGE("sinkPtr is null, compType = %{public}#X.", dhType);
1820         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
1821     }
1822     compSink_.insert(std::make_pair(dhType, sinkPtr));
1823     return DH_FWK_SUCCESS;
1824 }
1825 
UninitCompSink(DHType dhType)1826 int32_t ComponentManager::UninitCompSink(DHType dhType)
1827 {
1828     std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
1829     auto ret = ComponentLoader::GetInstance().ReleaseSink(dhType);
1830     if (ret != DH_FWK_SUCCESS) {
1831         DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1832         return ret;
1833     }
1834     compSink_.erase(dhType);
1835     return DH_FWK_SUCCESS;
1836 }
1837 
StopSource(DHType dhType,ActionResult & sourceResult)1838 int32_t ComponentManager::StopSource(DHType dhType, ActionResult &sourceResult)
1839 {
1840     DHLOGI("StopSource, dhType: %{public}#X", dhType);
1841     std::shared_lock<std::shared_mutex> lock(compSourceMutex_);
1842     if (compSource_.find(dhType) == compSource_.end()) {
1843         DHLOGE("Component for DHType: %{public}" PRIu32 " not init source handler.", (uint32_t)dhType);
1844         return ERR_DH_FWK_TYPE_NOT_EXIST;
1845     }
1846     auto sourcePtr = compSource_[dhType];
1847     if (sourcePtr == nullptr) {
1848         DHLOGE("comp source ptr is null.");
1849         return ERR_DH_FWK_SA_HANDLER_IS_NULL;
1850     }
1851     std::promise<int32_t> p;
1852     std::future<int32_t> f = p.get_future();
1853     std::thread([p = std::move(p), sourcePtr] () mutable {
1854         p.set_value(sourcePtr->ReleaseSource());
1855     }).detach();
1856     sourceResult.emplace(dhType, f.share());
1857     return DH_FWK_SUCCESS;
1858 }
1859 
StopSink(DHType dhType,ActionResult & sinkResult)1860 int32_t ComponentManager::StopSink(DHType dhType, ActionResult &sinkResult)
1861 {
1862     DHLOGI("StopSink, dhType: %{public}#X", dhType);
1863     std::shared_lock<std::shared_mutex> lock(compSinkMutex_);
1864     if (compSink_.find(dhType) == compSink_.end()) {
1865         DHLOGE("Component for DHType: %{public}" PRIu32 " not init sink handler.", (uint32_t)dhType);
1866         return ERR_DH_FWK_TYPE_NOT_EXIST;
1867     }
1868     auto sinkPtr = compSink_[dhType];
1869     if (sinkPtr == nullptr) {
1870         DHLOGE("comp sink ptr is null.");
1871         return ERR_DH_FWK_SA_HANDLER_IS_NULL;
1872     }
1873     std::promise<int32_t> p;
1874     std::future<int32_t> f = p.get_future();
1875     std::thread([p = std::move(p), sinkPtr, dhType] () mutable {
1876         p.set_value(sinkPtr->ReleaseSink());
1877         IHardwareHandler *hardwareHandler = nullptr;
1878         int32_t status = ComponentLoader::GetInstance().GetHardwareHandler(dhType, hardwareHandler);
1879         if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) {
1880             DHLOGE("GetHardwareHandler %{public}#X failed.", dhType);
1881             return status;
1882         }
1883         hardwareHandler->UnRegisterPluginListener();
1884         return status;
1885     }).detach();
1886     sinkResult.emplace(dhType, f.share());
1887     return DH_FWK_SUCCESS;
1888 }
1889 
DisableMetaSource(const std::string & networkId,const DHDescriptor & dhDescriptor,std::shared_ptr<IDistributedModemExt> dhModemExt,IDistributedHardwareSource * & sourcePtr)1890 int32_t ComponentManager::DisableMetaSource(const std::string &networkId, const DHDescriptor &dhDescriptor,
1891     std::shared_ptr<IDistributedModemExt> dhModemExt, IDistributedHardwareSource *&sourcePtr)
1892 {
1893     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1894     DHStatusSourceEnableInfoKey enableInfoKey {
1895         .networkId = networkId,
1896         .dhId = dhDescriptor.id
1897     };
1898     DHStatusCtrlKey ctrlKey {
1899         .uid = 0,
1900         .pid = 0
1901     };
1902 
1903     auto &status = dhSourceStatus_[dhDescriptor.dhType];
1904     auto &enableInfo = status.enableInfos[enableInfoKey];
1905 
1906     // Check if the business is being called repeatedly
1907     auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1908     if (statusCtrl.enableState == EnableState::DISABLED) {
1909         DHLOGE("Repeat call DisableSource, DhType = %{public}#X.", dhDescriptor.dhType);
1910         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1911     }
1912 
1913     // Check enable reference count
1914     if (enableInfo.refEnable > 1) {
1915         // Change status, we won't call back directly here because there is a lock
1916         statusCtrl.enableState = EnableState::DISABLED;
1917         enableInfo.refEnable--;
1918         status.refLoad--;
1919         return DH_FWK_SUCCESS;
1920     }
1921 
1922     // Check load reference count
1923     if (status.refLoad > 1) {
1924         DHLOGI("Meta disable, networkId = %{public}s", GetAnonyString(networkId).c_str());
1925         if (dhModemExt->Disable(networkId, sourcePtr) != DH_FWK_SUCCESS) {
1926             DHLOGE("Meta disable failed, networkId = %{public}s.", GetAnonyString(networkId).c_str());
1927         }
1928         // Change status, we won't call back directly here because there is a lock
1929         statusCtrl.enableState = EnableState::DISABLED;
1930         enableInfo.refEnable--;
1931         status.refLoad--;
1932         return DH_FWK_SUCCESS;
1933     }
1934 
1935     auto ret = DisableMetaSourceInternal(networkId, dhDescriptor, statusCtrl, enableInfo, status,
1936         dhModemExt, sourcePtr);
1937     if (ret != DH_FWK_SUCCESS) {
1938         DHLOGE("DisableMetaSource failed, ret = %{public}d.", ret);
1939         return ret;
1940     }
1941 
1942     return DH_FWK_SUCCESS;
1943 }
1944 
DisableMetaSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,DHStatusCtrl & statusCtrl,DHStatusEnableInfo & enableInfo,DHSourceStatus & status,std::shared_ptr<IDistributedModemExt> dhModemExt,IDistributedHardwareSource * & sourcePtr)1945 int32_t ComponentManager::DisableMetaSourceInternal(const std::string &networkId, const DHDescriptor &dhDescriptor,
1946     DHStatusCtrl &statusCtrl, DHStatusEnableInfo &enableInfo, DHSourceStatus &status,
1947     std::shared_ptr<IDistributedModemExt> dhModemExt, IDistributedHardwareSource *&sourcePtr)
1948 {
1949     auto ret = dhModemExt->Disable(networkId, sourcePtr);
1950     if (ret != DH_FWK_SUCCESS) {
1951         DHLOGE("Meta disable source failed, ret = %{public}d.", ret);
1952     }
1953     std::unordered_map<DHType, std::shared_future<int32_t>> sourceResult;
1954     ret = StopSource(dhDescriptor.dhType, sourceResult);
1955     if (ret != DH_FWK_SUCCESS) {
1956         DHLOGE("StopSource failed");
1957         return ret;
1958     }
1959     if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
1960         DHLOGE("StopSource timeout!");
1961         return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1962     }
1963     ret = UninitCompSource(dhDescriptor.dhType);
1964     if (ret != DH_FWK_SUCCESS) {
1965         DHLOGE("UninitCompSource failed, ret = %{public}d.", ret);
1966         return ret;
1967     }
1968     // Change status, we won't call back directly here because there is a lock
1969     statusCtrl.enableState = EnableState::DISABLED;
1970     enableInfo.refEnable = 0;
1971     status.refLoad = 0;
1972     return DH_FWK_SUCCESS;
1973 }
1974 
EnableMetaSource(const std::string & networkId,const DHDescriptor & dhDescriptor,std::shared_ptr<IDistributedModemExt> dhModemExt,IDistributedHardwareSource * & sourcePtr)1975 int32_t ComponentManager::EnableMetaSource(const std::string &networkId, const DHDescriptor &dhDescriptor,
1976     std::shared_ptr<IDistributedModemExt> dhModemExt, IDistributedHardwareSource *&sourcePtr)
1977 {
1978     DHLOGI("EnableMetaSource enter");
1979     std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1980     DHStatusSourceEnableInfoKey enableInfoKey { .networkId = networkId, .dhId = dhDescriptor.id };
1981     DHStatusCtrlKey ctrlKey { .uid = 0, .pid = 0 };
1982     auto &status = dhSourceStatus_[dhDescriptor.dhType];
1983     auto &enableInfo = status.enableInfos[enableInfoKey];
1984 
1985     // Check if the business is being called repeatedly
1986     auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1987     if (statusCtrl.enableState == EnableState::ENABLED) {
1988         DHLOGE("Repeat call EnableMetaSource, DhType = %{public}#X.", dhDescriptor.dhType);
1989         return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1990     }
1991 
1992     // Check enable reference count
1993     if (enableInfo.refEnable > 0) {
1994         // Change status, we won't call back directly here because there is a lock
1995         statusCtrl.enableState = EnableState::ENABLED;
1996         enableInfo.refEnable++;
1997         status.refLoad++;
1998         return DH_FWK_SUCCESS;
1999     }
2000 
2001     // Check load reference count
2002     if (status.refLoad > 0) {
2003         DHLOGI("Meta enable, networkId = %{public}s", GetAnonyString(networkId).c_str());
2004         if (dhModemExt->Enable(networkId, sourcePtr) != DH_FWK_SUCCESS) {
2005             DHLOGW("Meta enable failed, networkId = %{public}s.", GetAnonyString(networkId).c_str());
2006             return ERR_DH_FWK_PARA_INVALID;
2007         }
2008         // Change status, we won't call back directly here because there is a lock
2009         statusCtrl.enableState = EnableState::ENABLED;
2010         enableInfo.refEnable++;
2011         status.refLoad++;
2012         return DH_FWK_SUCCESS;
2013     }
2014 
2015     auto ret = EnableMetaSourceInternal(networkId, dhDescriptor, statusCtrl, enableInfo, status, dhModemExt, sourcePtr);
2016     if (ret != DH_FWK_SUCCESS) {
2017         DHLOGE("EnableMetaSource failed, ret = %{public}d.", ret);
2018         return ret;
2019     }
2020 
2021     return DH_FWK_SUCCESS;
2022 }
2023 
EnableMetaSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,DHStatusCtrl & statusCtrl,DHStatusEnableInfo & enableInfo,DHSourceStatus & status,std::shared_ptr<IDistributedModemExt> dhModemExt,IDistributedHardwareSource * & sourcePtr)2024 int32_t ComponentManager::EnableMetaSourceInternal(const std::string &networkId, const DHDescriptor &dhDescriptor,
2025     DHStatusCtrl &statusCtrl, DHStatusEnableInfo &enableInfo, DHSourceStatus &status,
2026     std::shared_ptr<IDistributedModemExt> dhModemExt, IDistributedHardwareSource *&sourcePtr)
2027 {
2028     auto ret = InitCompSource(dhDescriptor.dhType);
2029     if (ret != DH_FWK_SUCCESS) {
2030         DHLOGE("InitCompSource failed, ret = %{public}d.", ret);
2031         return ret;
2032     }
2033     std::unordered_map<DHType, std::shared_future<int32_t>> sourceResult;
2034     ret = StartSource(dhDescriptor.dhType, sourceResult);
2035     if (ret != DH_FWK_SUCCESS) {
2036         DHLOGE("StartSource failed");
2037         return ret;
2038     }
2039     if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
2040         DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue!");
2041         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
2042             "dhfwk start source failed.");
2043         UninitCompSource(dhDescriptor.dhType);
2044         return ERR_DH_FWK_COMPONENT_ENABLE_TIMEOUT;
2045     }
2046     ret = dhModemExt->Enable(networkId, sourcePtr);
2047     if (ret != DH_FWK_SUCCESS) {
2048         DHLOGE("EnableMeta failed, ret = %{public}d.", ret);
2049         std::unordered_map<DHType, std::shared_future<int32_t>> futureResult;
2050         StopSource(dhDescriptor.dhType, futureResult);
2051         UninitCompSource(dhDescriptor.dhType);
2052         return ret;
2053     }
2054     statusCtrl.enableState = EnableState::ENABLED;
2055     enableInfo.refEnable = 1;
2056     status.refLoad = 1;
2057     return ret;
2058 }
2059 } // namespace DistributedHardware
2060 } // namespace OHOS
2061