• 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 "componentloader/component_loader.h"
17 
18 #include <cinttypes>
19 #include <dlfcn.h>
20 #include <fstream>
21 #include <string>
22 
23 #include "config_policy_utils.h"
24 
25 #include "anonymous_string.h"
26 #include "constants.h"
27 #include "dh_context.h"
28 #include "dh_utils_hitrace.h"
29 #include "dh_utils_hisysevent.h"
30 #include "dh_utils_tool.h"
31 #include "hidump_helper.h"
32 #include "distributed_hardware_log.h"
33 #include "version_info.h"
34 #include "version_info_manager.h"
35 #include "version_manager.h"
36 
37 namespace OHOS {
38 namespace DistributedHardware {
39 #undef DH_LOG_TAG
40 #define DH_LOG_TAG "ComponentLoader"
41 
42 IMPLEMENT_SINGLE_INSTANCE(ComponentLoader);
43 using GetHardwareClass = IHardwareHandler *(*)();
44 using GetSourceHardwareClass = IDistributedHardwareSource *(*)();
45 using GetSinkHardwareClass = IDistributedHardwareSink *(*)();
46 namespace {
47 const std::string COMP_NAME = "name";
48 const std::string COMP_TYPE = "type";
49 const std::string COMP_HANDLER_LOC = "comp_handler_loc";
50 const std::string COMP_HANDLER_VERSION = "comp_handler_version";
51 const std::string COMP_SOURCE_LOC = "comp_source_loc";
52 const std::string COMP_SOURCE_VERSION = "comp_source_version";
53 const std::string COMP_SOURCE_SA_ID = "comp_source_sa_id";
54 const std::string COMP_SINK_LOC = "comp_sink_loc";
55 const std::string COMP_SINK_VERSION = "comp_sink_version";
56 const std::string COMP_SINK_SA_ID = "comp_sink_sa_id";
57 const std::string COMP_RESOURCE_DESC = "comp_resource_desc";
58 const std::string COMP_SUBTYPE = "subtype";
59 const std::string COMP_SENSITIVE = "sensitive";
60 
61 const std::string COMPONENTSLOAD_DISTRIBUTED_COMPONENTS = "distributed_components";
62 
63 const std::string DEFAULT_NAME = "";
64 const std::string DEFAULT_TYPE = "UNKNOWN";
65 const std::string DEFAULT_LOC = "";
66 const int32_t DEFAULT_SA_ID = -1;
67 const std::string DEFAULT_VERSION = "1.0";
68 
69 std::map<std::string, DHType> g_mapDhTypeName = {
70     { "UNKNOWN", DHType::UNKNOWN },
71     { "CAMERA", DHType::CAMERA },
72     { "AUDIO", DHType::AUDIO },
73     { "SCREEN", DHType::SCREEN },
74     { "GPS", DHType::GPS },
75     { "INPUT", DHType::INPUT },
76     { "HFP", DHType::HFP },
77     { "A2D", DHType::A2D },
78     { "VIRMODEM_AUDIO", DHType::VIRMODEM_AUDIO },
79     { "MODEM", DHType::MODEM },
80 };
81 
82 std::map<DHType, std::string> g_mapPartsParamName = {
83     { DHType::CAMERA, "sys.dhfwk.component.dcamera.enable" },
84     { DHType::AUDIO, "sys.dhfwk.component.daudio.enable" },
85     { DHType::SCREEN, "sys.dhfwk.component.dscreen.enable" },
86     { DHType::INPUT, "sys.dhfwk.component.dinput.enable" },
87 };
88 }
89 
Init()90 int32_t ComponentLoader::Init()
91 {
92     DHLOGI("start");
93     DHTraceStart(COMPONENT_LOAD_START);
94     int32_t ret = ParseConfig();
95     StoreLocalDHVersionInDB();
96     DHTraceEnd();
97 
98     return ret;
99 }
100 
GetAllCompTypes()101 std::vector<DHType> ComponentLoader::GetAllCompTypes()
102 {
103     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
104     std::vector<DHType> DHTypeALL;
105     for (std::map<DHType, CompHandler>::iterator it = compHandlerMap_.begin(); it != compHandlerMap_.end(); ++it) {
106         DHTypeALL.push_back(it->first);
107     }
108     return DHTypeALL;
109 }
110 
ParseComponent(const cJSON * json,CompConfig & cfg)111 int32_t ParseComponent(const cJSON *json, CompConfig &cfg)
112 {
113     cJSON *nameJson = cJSON_GetObjectItem(json, COMP_NAME.c_str());
114     if (!IsString(nameJson)) {
115         DHLOGE("COMP_NAME is invalid!");
116         return ERR_DH_FWK_JSON_PARSE_FAILED;
117     }
118     cfg.name = nameJson->valuestring;
119 
120     cJSON *typeJson = cJSON_GetObjectItem(json, COMP_TYPE.c_str());
121     if (!IsString(typeJson)) {
122         DHLOGE("COMP_TYPE is invalid!");
123         return ERR_DH_FWK_JSON_PARSE_FAILED;
124     }
125     cfg.type = g_mapDhTypeName[typeJson->valuestring];
126 
127     cJSON *handlerLocJson = cJSON_GetObjectItem(json, COMP_HANDLER_LOC.c_str());
128     if (!IsString(handlerLocJson)) {
129         DHLOGE("COMP_HANDLER_LOC is invalid!");
130         return ERR_DH_FWK_JSON_PARSE_FAILED;
131     }
132     cfg.compHandlerLoc = handlerLocJson->valuestring;
133 
134     cJSON *handlerVerJson = cJSON_GetObjectItem(json, COMP_HANDLER_VERSION.c_str());
135     if (!IsString(handlerVerJson)) {
136         DHLOGE("COMP_HANDLER_VERSION is invalid!");
137         return ERR_DH_FWK_JSON_PARSE_FAILED;
138     }
139     cfg.compHandlerVersion = handlerVerJson->valuestring;
140     return DH_FWK_SUCCESS;
141 }
142 
ParseSource(const cJSON * json,CompConfig & cfg)143 int32_t ParseSource(const cJSON *json, CompConfig &cfg)
144 {
145     cJSON *sourceLocJson = cJSON_GetObjectItem(json, COMP_SOURCE_LOC.c_str());
146     if (!IsString(sourceLocJson)) {
147         DHLOGE("COMP_SOURCE_LOC is invalid!");
148         return ERR_DH_FWK_JSON_PARSE_FAILED;
149     }
150     cfg.compSourceLoc = sourceLocJson->valuestring;
151 
152     cJSON *sourceVerJson = cJSON_GetObjectItem(json, COMP_SOURCE_VERSION.c_str());
153     if (!IsString(sourceVerJson)) {
154         DHLOGE("COMP_SOURCE_VERSION is invalid!");
155         return ERR_DH_FWK_JSON_PARSE_FAILED;
156     }
157     cfg.compSourceVersion = sourceVerJson->valuestring;
158 
159     cJSON *sourceSaIdJson = cJSON_GetObjectItem(json, COMP_SOURCE_SA_ID.c_str());
160     if (!IsInt32(sourceSaIdJson)) {
161         DHLOGE("COMP_SOURCE_SA_ID is invalid!");
162         return ERR_DH_FWK_JSON_PARSE_FAILED;
163     }
164     cfg.compSourceSaId = static_cast<int32_t>(sourceSaIdJson->valueint);
165     return DH_FWK_SUCCESS;
166 }
167 
ParseSink(const cJSON * json,CompConfig & cfg)168 int32_t ParseSink(const cJSON *json, CompConfig &cfg)
169 {
170     cJSON *sinkLocJson = cJSON_GetObjectItem(json, COMP_SINK_LOC.c_str());
171     if (!IsString(sinkLocJson)) {
172         DHLOGE("COMP_SINK_LOC is invalid!");
173         return ERR_DH_FWK_JSON_PARSE_FAILED;
174     }
175     cfg.compSinkLoc = sinkLocJson->valuestring;
176 
177     cJSON *sinkVerJson = cJSON_GetObjectItem(json, COMP_SINK_VERSION.c_str());
178     if (!IsString(sinkVerJson)) {
179         DHLOGE("COMP_SINK_VERSION is invalid!");
180         return ERR_DH_FWK_JSON_PARSE_FAILED;
181     }
182     cfg.compSinkVersion = sinkVerJson->valuestring;
183 
184     cJSON *sinkSaIdJson = cJSON_GetObjectItem(json, COMP_SINK_SA_ID.c_str());
185     if (!IsInt32(sinkSaIdJson)) {
186         DHLOGE("COMP_SINK_SA_ID is invalid!");
187         return ERR_DH_FWK_JSON_PARSE_FAILED;
188     }
189     cfg.compSinkSaId = static_cast<int32_t>(sinkSaIdJson->valueint);
190     return DH_FWK_SUCCESS;
191 }
192 
ParseResourceDesc(const cJSON * json,CompConfig & cfg)193 int32_t ParseResourceDesc(const cJSON *json, CompConfig &cfg)
194 {
195     cJSON *resouceDescJson = cJSON_GetObjectItem(json, COMP_RESOURCE_DESC.c_str());
196     if (!IsArray(resouceDescJson)) {
197         DHLOGE("COMP_RESOURCE_DESC is invalid!");
198         return ERR_DH_FWK_JSON_PARSE_FAILED;
199     }
200     cJSON *element = nullptr;
201     cJSON_ArrayForEach(element, resouceDescJson) {
202         ResourceDesc desc;
203         cJSON *subtypeJson = cJSON_GetObjectItem(element, COMP_SUBTYPE.c_str());
204         if (!IsString(subtypeJson)) {
205             DHLOGE("COMP_SUBTYPE is invalid!");
206             return ERR_DH_FWK_JSON_PARSE_FAILED;
207         }
208         desc.subtype = subtypeJson->valuestring;
209 
210         cJSON *sensitive = cJSON_GetObjectItem(element, COMP_SENSITIVE.c_str());
211         if (!IsBool(sensitive)) {
212             DHLOGE("COMP_SENSITIVE is invalid!");
213             return ERR_DH_FWK_JSON_PARSE_FAILED;
214         }
215         if (cJSON_IsTrue(sensitive)) {
216             desc.sensitiveValue = true;
217         } else {
218             desc.sensitiveValue = false;
219         }
220         cfg.compResourceDesc.push_back(desc);
221     }
222     return DH_FWK_SUCCESS;
223 }
224 
from_json(const cJSON * json,CompConfig & cfg)225 void from_json(const cJSON *json, CompConfig &cfg)
226 {
227     if (ParseComponent(json, cfg) != DH_FWK_SUCCESS) {
228         DHLOGE("ParseComponent is failed");
229         return;
230     }
231     if (ParseSource(json, cfg) != DH_FWK_SUCCESS) {
232         DHLOGE("ParseSource is failed");
233         return;
234     }
235     if (ParseSink(json, cfg) != DH_FWK_SUCCESS) {
236         DHLOGE("ParseSink is failed");
237         return;
238     }
239     if (ParseResourceDesc(json, cfg) != DH_FWK_SUCCESS) {
240         DHLOGE("ParseResourceDesc is failed");
241         return;
242     }
243 }
244 
GetCompVersionFromComConfig(const CompConfig & cCfg)245 CompVersion ComponentLoader::GetCompVersionFromComConfig(const CompConfig& cCfg)
246 {
247     CompVersion compVersions;
248     compVersions.dhType = cCfg.type;
249     compVersions.name = cCfg.name;
250     compVersions.handlerVersion = cCfg.compHandlerVersion;
251     compVersions.sinkVersion = cCfg.compSinkVersion;
252     compVersions.sourceVersion = cCfg.compSourceVersion;
253     compVersions.haveFeature = cCfg.haveFeature;
254     compVersions.sourceFeatureFilters = cCfg.sourceFeatureFilters;
255     compVersions.sinkSupportedFeatures = cCfg.sinkSupportedFeatures;
256     return compVersions;
257 }
258 
CheckComponentEnable(const CompConfig & config)259 bool ComponentLoader::CheckComponentEnable(const CompConfig &config)
260 {
261     auto item = g_mapPartsParamName.find(config.type);
262     if (item == g_mapPartsParamName.end()) {
263         DHLOGI("Crrent component is enabled by default.");
264         return true;
265     }
266     bool isEnable = false;
267     if (!GetSysPara((item->second).c_str(), isEnable)) {
268         DHLOGE("sys para: %{public}s get failed.", (item->second).c_str());
269         return false;
270     }
271     DHLOGI("Component type: %{public}u, enable flag: %{public}d.", config.type, isEnable);
272     return isEnable;
273 }
274 
GetCompPathAndVersion(const std::string & jsonStr,std::map<DHType,CompConfig> & dhtypeMap)275 int32_t ComponentLoader::GetCompPathAndVersion(const std::string &jsonStr, std::map<DHType, CompConfig> &dhtypeMap)
276 {
277     if (!IsJsonLengthValid(jsonStr)) {
278         return ERR_DH_FWK_PARA_INVALID;
279     }
280     cJSON *root = cJSON_Parse(jsonStr.c_str());
281     if (root == NULL) {
282         DHLOGE("jsonStr parse failed");
283         return ERR_DH_FWK_JSON_PARSE_FAILED;
284     }
285     cJSON *components = cJSON_GetObjectItem(root, COMPONENTSLOAD_DISTRIBUTED_COMPONENTS.c_str());
286     if (!IsArray(components)) {
287         DHLOGE("distributed_components is not an array");
288         cJSON_Delete(root);
289         return ERR_DH_FWK_PARA_INVALID;
290     }
291 
292     size_t compSize = static_cast<size_t>(cJSON_GetArraySize(components));
293     if (compSize == 0 || compSize > MAX_COMP_SIZE) {
294         DHLOGE("CompConfig size is invalid!");
295         cJSON_Delete(root);
296         return ERR_DH_FWK_PARA_INVALID;
297     }
298     cJSON *component = nullptr;
299     cJSON_ArrayForEach(component, components) {
300         CompConfig config;
301         ParseCompConfigFromJson(component, config);
302         dhtypeMap.insert(std::pair<DHType, CompConfig>(config.type, config));
303         localDHVersion_.compVersions.insert(
304             std::pair<DHType, CompVersion>(config.type, GetCompVersionFromComConfig(config)));
305     }
306     cJSON_Delete(root);
307     isLocalVersionInit_.store(true);
308     return DH_FWK_SUCCESS;
309 }
310 
ParseCompConfigFromJson(cJSON * component,CompConfig & config)311 void ComponentLoader::ParseCompConfigFromJson(cJSON *component, CompConfig &config)
312 {
313     cJSON *nameJson = cJSON_GetObjectItem(component, COMP_NAME.c_str());
314     if (IsString(nameJson)) {
315         config.name = nameJson->valuestring;
316     }
317     cJSON *typeJson = cJSON_GetObjectItem(component, COMP_TYPE.c_str());
318     if (IsString(typeJson)) {
319         config.type = g_mapDhTypeName[typeJson->valuestring];
320     }
321     cJSON *handlerLocJson = cJSON_GetObjectItem(component, COMP_HANDLER_LOC.c_str());
322     if (IsString(handlerLocJson)) {
323         config.compHandlerLoc = handlerLocJson->valuestring;
324     }
325     cJSON *handlerVerJson = cJSON_GetObjectItem(component, COMP_HANDLER_VERSION.c_str());
326     if (IsString(handlerVerJson)) {
327         config.compHandlerVersion = handlerVerJson->valuestring;
328     }
329     cJSON *sourceLocJson = cJSON_GetObjectItem(component, COMP_SOURCE_LOC.c_str());
330     if (IsString(sourceLocJson)) {
331         config.compSourceLoc = sourceLocJson->valuestring;
332     }
333     cJSON *sourceVerJson = cJSON_GetObjectItem(component, COMP_SOURCE_VERSION.c_str());
334     if (IsString(sourceVerJson)) {
335         config.compSourceVersion = sourceVerJson->valuestring;
336     }
337     cJSON *sourceSaIdJson = cJSON_GetObjectItem(component, COMP_SOURCE_SA_ID.c_str());
338     if (IsInt32(sourceSaIdJson)) {
339         config.compSourceSaId = static_cast<int32_t>(sourceSaIdJson->valueint);
340     }
341     cJSON *sinkLocJson = cJSON_GetObjectItem(component, COMP_SINK_LOC.c_str());
342     if (IsString(sinkLocJson)) {
343         config.compSinkLoc = sinkLocJson->valuestring;
344     }
345     cJSON *sinkVerJson = cJSON_GetObjectItem(component, COMP_SINK_VERSION.c_str());
346     if (IsString(sinkVerJson)) {
347         config.compSinkVersion = sinkVerJson->valuestring;
348     }
349     cJSON *sinkSaIdJson = cJSON_GetObjectItem(component, COMP_SINK_SA_ID.c_str());
350     if (IsInt32(sinkSaIdJson)) {
351         config.compSinkSaId = static_cast<int32_t>(sinkSaIdJson->valueint);
352     }
353     cJSON *resourceDescs = cJSON_GetObjectItem(component, COMP_RESOURCE_DESC.c_str());
354     if (IsArray(resourceDescs)) {
355         ParseResourceDescFromJson(resourceDescs, config);
356     }
357     CheckAndParseFeatures(component, config);
358 }
359 
ParseResourceDescFromJson(cJSON * resourceDescs,CompConfig & config)360 void ComponentLoader::ParseResourceDescFromJson(cJSON *resourceDescs, CompConfig &config)
361 {
362     cJSON *resourceDesc = nullptr;
363     cJSON_ArrayForEach(resourceDesc, resourceDescs) {
364         bool sensitiveValue;
365         cJSON *sensitive = cJSON_GetObjectItem(resourceDesc, COMP_SENSITIVE.c_str());
366         if (!IsBool(sensitive)) {
367             DHLOGE("COMP_SUBTYPE is invalid!");
368             return;
369         }
370         if (cJSON_IsTrue(sensitive)) {
371             sensitiveValue = true;
372         } else {
373             sensitiveValue = false;
374         }
375         ResourceDesc resource;
376         cJSON *subtypeJson = cJSON_GetObjectItem(resourceDesc, COMP_SUBTYPE.c_str());
377         if (!IsString(subtypeJson)) {
378             DHLOGE("COMP_SUBTYPE is invalid!");
379             return;
380         }
381         resource.subtype = subtypeJson->valuestring;
382         resource.sensitiveValue = sensitiveValue;
383         config.compResourceDesc.push_back(resource);
384     }
385 }
386 
ParseSourceFeatureFiltersFromJson(cJSON * sourceFeatureFilters,CompConfig & config)387 void ComponentLoader::ParseSourceFeatureFiltersFromJson(cJSON *sourceFeatureFilters, CompConfig &config)
388 {
389     cJSON *filter = nullptr;
390     config.sourceFeatureFilters.clear();
391     cJSON_ArrayForEach(filter, sourceFeatureFilters) {
392         config.sourceFeatureFilters.push_back(filter->valuestring);
393     }
394 }
395 
ParseSinkSupportedFeaturesFromJson(cJSON * sinkSupportedFeatures,CompConfig & config)396 void ComponentLoader::ParseSinkSupportedFeaturesFromJson(cJSON *sinkSupportedFeatures, CompConfig &config)
397 {
398     cJSON *feature = nullptr;
399     config.sinkSupportedFeatures.clear();
400     cJSON_ArrayForEach(feature, sinkSupportedFeatures) {
401         config.sinkSupportedFeatures.push_back(feature->valuestring);
402     }
403 }
404 
CheckAndParseFeatures(cJSON * component,CompConfig & config)405 void ComponentLoader::CheckAndParseFeatures(cJSON *component, CompConfig &config)
406 {
407     cJSON *sourceFeatureFilters = cJSON_GetObjectItem(component, SOURCE_FEATURE_FILTER.c_str());
408     cJSON *sinkSupportedFeatures = cJSON_GetObjectItem(component, SINK_SUPPORTED_FEATURE.c_str());
409     if (sourceFeatureFilters || sinkSupportedFeatures) {
410         config.haveFeature = true;
411         if (IsArray(sourceFeatureFilters)) {
412             ParseSourceFeatureFiltersFromJson(sourceFeatureFilters, config);
413         }
414         if (IsArray(sinkSupportedFeatures)) {
415             ParseSinkSupportedFeaturesFromJson(sinkSupportedFeatures, config);
416         }
417     } else {
418         config.haveFeature = false;
419     }
420 }
421 
GetLocalDHVersion(DHVersion & dhVersion)422 int32_t ComponentLoader::GetLocalDHVersion(DHVersion &dhVersion)
423 {
424     if (!isLocalVersionInit_.load()) {
425         DHLOGE("get local DHVersion fail");
426         return ERR_DH_FWK_LOADER_GET_LOCAL_VERSION_FAIL;
427     }
428     dhVersion = localDHVersion_;
429     return DH_FWK_SUCCESS;
430 }
431 
StoreLocalDHVersionInDB()432 void ComponentLoader::StoreLocalDHVersionInDB()
433 {
434     if (!isLocalVersionInit_.load()) {
435         DHLOGE("Store local DHVersion fail");
436         return;
437     }
438     VersionInfo versionInfo;
439     versionInfo.dhVersion = VersionManager::GetInstance().GetLocalDeviceVersion();
440     versionInfo.deviceId = DHContext::GetInstance().GetDeviceInfo().deviceId;
441     versionInfo.compVersions = localDHVersion_.compVersions;
442     VersionInfoManager::GetInstance()->AddVersion(versionInfo);
443 }
444 
GetHandler(const std::string & soName)445 void *ComponentLoader::GetHandler(const std::string &soName)
446 {
447     if (soName.length() == 0 || soName.length() > PATH_MAX) {
448         DHLOGE("File canonicalization failed, soName: %{public}s", soName.c_str());
449         return nullptr;
450     }
451     void *pHandler = dlopen(soName.c_str(), RTLD_LAZY | RTLD_NODELETE);
452     if (pHandler == nullptr) {
453         DHLOGE("so: %{public}s load failed, failed reason: %{public}s", soName.c_str(), dlerror());
454         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
455             "dhfwk so open failed, soname : " + soName);
456         return nullptr;
457     }
458     return pHandler;
459 }
460 
GetAllHandler(std::map<DHType,CompConfig> & dhtypeMap)461 void ComponentLoader::GetAllHandler(std::map<DHType, CompConfig> &dhtypeMap)
462 {
463     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
464     std::map<DHType, CompConfig>::iterator itor;
465     for (itor = dhtypeMap.begin(); itor != dhtypeMap.end(); ++itor) {
466         CompHandler comHandler;
467         comHandler.type = itor->second.type;
468         comHandler.sourceSaId = itor->second.compSourceSaId;
469         comHandler.sinkSaId = itor->second.compSinkSaId;
470         std::vector<ResourceDesc> compResourceDesc = itor->second.compResourceDesc;
471         for (auto it = compResourceDesc.begin(); it != compResourceDesc.end(); it++) {
472             resDescMap_[it->subtype] = it->sensitiveValue;
473         }
474         comHandler.compConfig = itor->second;
475         compHandlerMap_[itor->second.type] = comHandler;
476     }
477 }
478 
GetHardwareHandler(const DHType dhType,IHardwareHandler * & hardwareHandlerPtr)479 int32_t ComponentLoader::GetHardwareHandler(const DHType dhType, IHardwareHandler *&hardwareHandlerPtr)
480 {
481     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
482     auto iter = compHandlerMap_.find(dhType);
483     if (iter == compHandlerMap_.end()) {
484         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
485         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
486     }
487     CompHandler &compHandler = iter->second;
488     if (compHandler.hardwareHandler == nullptr) {
489         compHandler.hardwareHandler = GetHandler(compHandler.compConfig.compHandlerLoc);
490         if (compHandler.hardwareHandler == nullptr) {
491             DHLOGE("get hardware handler is null, dhType: %{public}" PRIu32, (uint32_t)dhType);
492             return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
493         }
494     }
495     GetHardwareClass getHardwareClassHandler = (GetHardwareClass)dlsym(compHandler.hardwareHandler,
496         COMPONENT_LOADER_GET_HARDWARE_HANDLER.c_str());
497     if (getHardwareClassHandler == nullptr) {
498         DHLOGE("get getHardwareClassHandler is null, failed reason : %{public}s", dlerror());
499         ReleaseHandler(compHandler.hardwareHandler);
500         compHandler.hardwareHandler = nullptr;
501         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
502     }
503     hardwareHandlerPtr = getHardwareClassHandler();
504     return DH_FWK_SUCCESS;
505 }
506 
GetSource(const DHType dhType,IDistributedHardwareSource * & sourcePtr)507 int32_t ComponentLoader::GetSource(const DHType dhType, IDistributedHardwareSource *&sourcePtr)
508 {
509     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
510     auto iter = compHandlerMap_.find(dhType);
511     if (iter == compHandlerMap_.end()) {
512         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
513         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
514     }
515     CompHandler &compHandler = iter->second;
516     if (compHandler.sourceHandler == nullptr) {
517         compHandler.sourceHandler = GetHandler(compHandler.compConfig.compSourceLoc);
518         if (compHandler.sourceHandler == nullptr) {
519             DHLOGE("get source handler is null, dhType: %{public}" PRIu32, (uint32_t)dhType);
520             return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
521         }
522     }
523     GetSourceHardwareClass getSourceHardClassHandler = (GetSourceHardwareClass)dlsym(
524         compHandler.sourceHandler, COMPONENT_LOADER_GET_SOURCE_HANDLER.c_str());
525     if (getSourceHardClassHandler == nullptr) {
526         DHLOGE("get getSourceHardClassHandler is null, failed reason : %{public}s", dlerror());
527         ReleaseHandler(compHandler.sourceHandler);
528         compHandler.sourceHandler = nullptr;
529         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
530     }
531     sourcePtr = getSourceHardClassHandler();
532     return DH_FWK_SUCCESS;
533 }
534 
GetSink(const DHType dhType,IDistributedHardwareSink * & sinkPtr)535 int32_t ComponentLoader::GetSink(const DHType dhType, IDistributedHardwareSink *&sinkPtr)
536 {
537     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
538     auto iter = compHandlerMap_.find(dhType);
539     if (iter == compHandlerMap_.end()) {
540         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
541         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
542     }
543     CompHandler &compHandler = iter->second;
544     if (compHandler.sinkHandler == nullptr) {
545         compHandler.sinkHandler = GetHandler(compHandler.compConfig.compSinkLoc);
546         if (compHandler.sinkHandler == nullptr) {
547             DHLOGE("get sink handler is null, dhType: %{public}" PRIu32, (uint32_t)dhType);
548             return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
549         }
550     }
551     GetSinkHardwareClass getSinkHardwareClassHandler =
552         (GetSinkHardwareClass)dlsym(compHandler.sinkHandler, COMPONENT_LOADER_GET_SINK_HANDLER.c_str());
553     if (getSinkHardwareClassHandler == nullptr) {
554         DHLOGE("get getSinkHardwareClassHandler is null, failed reason : %{public}s", dlerror());
555         ReleaseHandler(compHandler.sinkHandler);
556         compHandler.sinkHandler = nullptr;
557         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
558     }
559     sinkPtr = getSinkHardwareClassHandler();
560     return DH_FWK_SUCCESS;
561 }
562 
Readfile(const std::string & filePath)563 std::string ComponentLoader::Readfile(const std::string &filePath)
564 {
565     std::ifstream infile;
566     std::string sLine;
567     std::string sAll = "";
568     infile.open(filePath);
569     if (!infile.is_open()) {
570         DHLOGE("filePath: %{public}s Readfile fail", filePath.c_str());
571         return sAll;
572     }
573 
574     while (getline(infile, sLine)) {
575         sAll.append(sLine);
576     }
577     infile.close();
578     return sAll;
579 }
580 
ParseConfig()581 int32_t ComponentLoader::ParseConfig()
582 {
583     std::map<DHType, CompConfig> dhtypeMap;
584     int32_t ret;
585     DHLOGI("ParseConfig start");
586     char buf[MAX_PATH_LEN] = {0};
587     char path[PATH_MAX + 1] = {0x00};
588     char *profilePath = GetOneCfgFile(COMPONENTSLOAD_PROFILE_PATH, buf, MAX_PATH_LEN);
589     if (profilePath == nullptr) {
590         DHLOGE("profilePath is null.");
591         return ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL;
592     }
593 
594     if (strlen(profilePath) == 0 || strlen(profilePath) > PATH_MAX || realpath(profilePath, path) == nullptr) {
595         std::string comProfilePath(profilePath);
596         DHLOGE("File connicailization failed, comProfilePath: %{public}s.", GetAnonyString(comProfilePath).c_str());
597         return ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL;
598     }
599     std::string componentProfilePath(path);
600     std::string jsonStr = Readfile(componentProfilePath);
601     if (!IsMessageLengthValid(jsonStr)) {
602         return ERR_DH_FWK_LOADER_CONFIG_JSON_INVALID;
603     }
604     ret = GetCompPathAndVersion(jsonStr, dhtypeMap);
605     if (ret != DH_FWK_SUCCESS) {
606         return ret;
607     }
608     GetAllHandler(dhtypeMap);
609     return DH_FWK_SUCCESS;
610 }
611 
ReleaseHandler(void * & handler)612 int32_t ComponentLoader::ReleaseHandler(void *&handler)
613 {
614     if (handler == nullptr) {
615         DHLOGE("handler is null.");
616         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
617     }
618 
619     if (dlclose(handler) != 0) {
620         DHLOGE("dlclose failed.");
621         return ERR_DH_FWK_LOADER_DLCLOSE_FAIL;
622     }
623     handler = nullptr;
624     return DH_FWK_SUCCESS;
625 }
626 
UnInit()627 int32_t ComponentLoader::UnInit()
628 {
629     DHLOGI("release all handler");
630     DHTraceStart(COMPONENT_RELEASE_START);
631     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
632     for (auto iter = compHandlerMap_.begin(); iter != compHandlerMap_.end(); ++iter) {
633         if (iter->second.sinkHandler) {
634             ReleaseHandler(iter->second.sinkHandler);
635         }
636         if (iter->second.sourceHandler) {
637             ReleaseHandler(iter->second.sourceHandler);
638         }
639         if (iter->second.hardwareHandler) {
640             ReleaseHandler(iter->second.hardwareHandler);
641         }
642     }
643     compHandlerMap_.clear();
644     resDescMap_.clear();
645     DHTraceEnd();
646     return DH_FWK_SUCCESS;
647 }
648 
ReleaseHardwareHandler(const DHType dhType)649 int32_t ComponentLoader::ReleaseHardwareHandler(const DHType dhType)
650 {
651     if (!IsDHTypeExist(dhType)) {
652         return ERR_DH_FWK_TYPE_NOT_EXIST;
653     }
654     if (!IsDHTypeHandlerLoaded(dhType)) {
655         return ERR_DH_FWK_LOADER_HANDLER_UNLOAD;
656     }
657     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].hardwareHandler);
658     if (ret) {
659         DHLOGE("fail, dhType: %{public}#X", dhType);
660         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
661             dhType, ret, "dhfwk release hardware handler failed.");
662     }
663     compHandlerMap_[dhType].hardwareHandler = nullptr;
664     return ret;
665 }
666 
ReleaseSource(const DHType dhType)667 int32_t ComponentLoader::ReleaseSource(const DHType dhType)
668 {
669     if (!IsDHTypeExist(dhType)) {
670         return ERR_DH_FWK_TYPE_NOT_EXIST;
671     }
672     if (!IsDHTypeSourceLoaded(dhType)) {
673         return ERR_DH_FWK_LOADER_SOURCE_UNLOAD;
674     }
675     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sourceHandler);
676     if (ret) {
677         DHLOGE("fail, dhType: %{public}#X", dhType);
678         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
679             dhType, ret, "dhfwk release source failed.");
680     }
681     compHandlerMap_[dhType].sourceHandler = nullptr;
682     return ret;
683 }
684 
ReleaseSink(const DHType dhType)685 int32_t ComponentLoader::ReleaseSink(const DHType dhType)
686 {
687     if (!IsDHTypeExist(dhType)) {
688         return ERR_DH_FWK_TYPE_NOT_EXIST;
689     }
690     if (!IsDHTypeSinkLoaded(dhType)) {
691         return ERR_DH_FWK_LOADER_SINK_UNLOAD;
692     }
693     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sinkHandler);
694     if (ret) {
695         DHLOGE("fail, dhType: %{public}#X", dhType);
696         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
697             dhType, ret, "dhfwk release sink failed.");
698     }
699     compHandlerMap_[dhType].sinkHandler = nullptr;
700     return ret;
701 }
702 
IsDHTypeExist(DHType dhType)703 bool ComponentLoader::IsDHTypeExist(DHType dhType)
704 {
705     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
706         DHLOGE("fail, dhType: %{public}#X not exist", dhType);
707         return false;
708     }
709     return true;
710 }
711 
IsDHTypeSinkLoaded(DHType dhType)712 bool ComponentLoader::IsDHTypeSinkLoaded(DHType dhType)
713 {
714     if (compHandlerMap_[dhType].sinkHandler == nullptr) {
715         DHLOGE("fail, dhType: %{public}#X sink not loaded", dhType);
716         return false;
717     }
718     return true;
719 }
720 
IsDHTypeSourceLoaded(DHType dhType)721 bool ComponentLoader::IsDHTypeSourceLoaded(DHType dhType)
722 {
723     if (compHandlerMap_[dhType].sourceHandler == nullptr) {
724         DHLOGE("fail, dhType: %{public}#X source not loaded", dhType);
725         return false;
726     }
727     return true;
728 }
729 
IsDHTypeHandlerLoaded(DHType dhType)730 bool ComponentLoader::IsDHTypeHandlerLoaded(DHType dhType)
731 {
732     if (compHandlerMap_[dhType].hardwareHandler == nullptr) {
733         DHLOGE("fail, dhType: %{public}#X handler not loaded", dhType);
734         return false;
735     }
736     return true;
737 }
738 
GetSourceSaId(const DHType dhType)739 int32_t ComponentLoader::GetSourceSaId(const DHType dhType)
740 {
741     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
742     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
743         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
744         return DEFAULT_SA_ID;
745     }
746     return compHandlerMap_[dhType].sourceSaId;
747 }
748 
GetDHTypeBySrcSaId(const int32_t saId)749 DHType ComponentLoader::GetDHTypeBySrcSaId(const int32_t saId)
750 {
751     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
752     DHType type = DHType::UNKNOWN;
753     for (const auto &handler : compHandlerMap_) {
754         if (handler.second.sourceSaId == saId) {
755             type = handler.second.type;
756             break;
757         }
758     }
759     return type;
760 }
761 
GetCompResourceDesc()762 std::map<std::string, bool> ComponentLoader::GetCompResourceDesc()
763 {
764     return resDescMap_;
765 }
766 
GetSource(const DHType dhType)767 int32_t ComponentLoader::GetSource(const DHType dhType)
768 {
769     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
770     auto iter = compHandlerMap_.find(dhType);
771     if (iter == compHandlerMap_.end()) {
772         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
773         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
774     }
775     CompHandler &compHandler = iter->second;
776     if (compHandler.sourceHandler != nullptr) {
777         DHLOGE("sourceHandler is loaded.");
778         return ERR_DH_FWK_LOADER_SOURCE_LOAD;
779     }
780     compHandler.sourceHandler = GetHandler(compHandler.compConfig.compSourceLoc);
781     return DH_FWK_SUCCESS;
782 }
783 
GetSink(const DHType dhType)784 int32_t ComponentLoader::GetSink(const DHType dhType)
785 {
786     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
787     auto iter = compHandlerMap_.find(dhType);
788     if (iter == compHandlerMap_.end()) {
789         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
790         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
791     }
792     CompHandler &compHandler = iter->second;
793     if (compHandler.sinkHandler != nullptr) {
794         DHLOGE("sinkHandler is loaded.");
795         return ERR_DH_FWK_LOADER_SINK_LOAD;
796     }
797     compHandler.sinkHandler = GetHandler(compHandler.compConfig.compSinkLoc);
798     return DH_FWK_SUCCESS;
799 }
800 
GetHardwareHandler(const DHType dhType)801 int32_t ComponentLoader::GetHardwareHandler(const DHType dhType)
802 {
803     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
804     auto iter = compHandlerMap_.find(dhType);
805     if (iter == compHandlerMap_.end()) {
806         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
807         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
808     }
809     CompHandler &compHandler = iter->second;
810     if (compHandler.hardwareHandler != nullptr) {
811         DHLOGE("hardwareHandler is loaded.");
812         return ERR_DH_FWK_LOADER_HANDLER_LOAD;
813     }
814     compHandler.hardwareHandler = GetHandler(compHandler.compConfig.compHandlerLoc);
815     return DH_FWK_SUCCESS;
816 }
817 
IsDHTypeSupport(DHType dhType)818 bool ComponentLoader::IsDHTypeSupport(DHType dhType)
819 {
820     return IsDHTypeExist(dhType);
821 }
822 } // namespace DistributedHardware
823 } // namespace OHOS
824