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