1 /*
2  * Copyright (c) 2021-2024 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     if (!IsString(json, COMP_NAME)) {
114         DHLOGE("COMP_NAME is invalid!");
115         return ERR_DH_FWK_JSON_PARSE_FAILED;
116     }
117     cfg.name = cJSON_GetObjectItem(json, COMP_NAME.c_str())->valuestring;
118     if (!IsString(json, COMP_TYPE)) {
119         DHLOGE("COMP_TYPE is invalid!");
120         return ERR_DH_FWK_JSON_PARSE_FAILED;
121     }
122     cfg.type = g_mapDhTypeName[cJSON_GetObjectItem(json, COMP_TYPE.c_str())->valuestring];
123     if (!IsString(json, COMP_HANDLER_LOC)) {
124         DHLOGE("COMP_HANDLER_LOC is invalid!");
125         return ERR_DH_FWK_JSON_PARSE_FAILED;
126     }
127     cfg.compHandlerLoc = cJSON_GetObjectItem(json, COMP_HANDLER_LOC.c_str())->valuestring;
128     if (!IsString(json, COMP_HANDLER_VERSION)) {
129         DHLOGE("COMP_HANDLER_VERSION is invalid!");
130         return ERR_DH_FWK_JSON_PARSE_FAILED;
131     }
132     cfg.compHandlerVersion = cJSON_GetObjectItem(json, COMP_HANDLER_VERSION.c_str())->valuestring;
133     return DH_FWK_SUCCESS;
134 }
135 
ParseSource(const cJSON * json,CompConfig & cfg)136 int32_t ParseSource(const cJSON *json, CompConfig &cfg)
137 {
138     if (!IsString(json, COMP_SOURCE_LOC)) {
139         DHLOGE("COMP_SOURCE_LOC is invalid!");
140         return ERR_DH_FWK_JSON_PARSE_FAILED;
141     }
142     cfg.compSourceLoc = cJSON_GetObjectItem(json, COMP_SOURCE_LOC.c_str())->valuestring;
143     if (!IsString(json, COMP_SOURCE_VERSION)) {
144         DHLOGE("COMP_SOURCE_VERSION is invalid!");
145         return ERR_DH_FWK_JSON_PARSE_FAILED;
146     }
147     cfg.compSourceVersion = cJSON_GetObjectItem(json, COMP_SOURCE_VERSION.c_str())->valuestring;
148     if (!IsInt32(json, COMP_SOURCE_SA_ID)) {
149         DHLOGE("COMP_SOURCE_SA_ID is invalid!");
150         return ERR_DH_FWK_JSON_PARSE_FAILED;
151     }
152     cfg.compSourceSaId = static_cast<int32_t>(cJSON_GetObjectItem(json, COMP_SOURCE_SA_ID.c_str())->valuedouble);
153     return DH_FWK_SUCCESS;
154 }
155 
ParseSink(const cJSON * json,CompConfig & cfg)156 int32_t ParseSink(const cJSON *json, CompConfig &cfg)
157 {
158     if (!IsString(json, COMP_SINK_LOC)) {
159         DHLOGE("COMP_SINK_LOC is invalid!");
160         return ERR_DH_FWK_JSON_PARSE_FAILED;
161     }
162     cfg.compSinkLoc = cJSON_GetObjectItem(json, COMP_SINK_LOC.c_str())->valuestring;
163     if (!IsString(json, COMP_SINK_VERSION)) {
164         DHLOGE("COMP_SINK_VERSION is invalid!");
165         return ERR_DH_FWK_JSON_PARSE_FAILED;
166     }
167     cfg.compSinkVersion = cJSON_GetObjectItem(json, COMP_SINK_VERSION.c_str())->valuestring;
168     if (!IsInt32(json, COMP_SINK_SA_ID)) {
169         DHLOGE("COMP_SINK_SA_ID is invalid!");
170         return ERR_DH_FWK_JSON_PARSE_FAILED;
171     }
172     cfg.compSinkSaId = static_cast<int32_t>(cJSON_GetObjectItem(json, COMP_SINK_SA_ID.c_str())->valuedouble);
173     return DH_FWK_SUCCESS;
174 }
175 
ParseResourceDesc(const cJSON * json,CompConfig & cfg)176 int32_t ParseResourceDesc(const cJSON *json, CompConfig &cfg)
177 {
178     if (!IsArray(json, COMP_RESOURCE_DESC)) {
179         DHLOGE("COMP_RESOURCE_DESC is invalid!");
180         return ERR_DH_FWK_JSON_PARSE_FAILED;
181     }
182     cJSON *resourceDescArray = cJSON_GetObjectItem(json, COMP_RESOURCE_DESC.c_str());
183     cJSON *element = nullptr;
184     cJSON_ArrayForEach(element, resourceDescArray) {
185         ResourceDesc desc;
186         if (!IsString(element, COMP_SUBTYPE)) {
187             DHLOGE("COMP_SUBTYPE is invalid!");
188             return ERR_DH_FWK_JSON_PARSE_FAILED;
189         }
190         desc.subtype = cJSON_GetObjectItem(element, COMP_SUBTYPE.c_str())->valuestring;
191         cJSON *sensitive = cJSON_GetObjectItem(element, COMP_SENSITIVE.c_str());
192         if (cJSON_IsTrue(sensitive)) {
193             desc.sensitiveValue = true;
194         } else {
195             desc.sensitiveValue = false;
196         }
197         cfg.compResourceDesc.push_back(desc);
198     }
199     return DH_FWK_SUCCESS;
200 }
201 
from_json(const cJSON * json,CompConfig & cfg)202 void from_json(const cJSON *json, CompConfig &cfg)
203 {
204     if (ParseComponent(json, cfg) != DH_FWK_SUCCESS) {
205         DHLOGE("ParseComponent is failed");
206         return;
207     }
208     if (ParseSource(json, cfg) != DH_FWK_SUCCESS) {
209         DHLOGE("ParseSource is failed");
210         return;
211     }
212     if (ParseSink(json, cfg) != DH_FWK_SUCCESS) {
213         DHLOGE("ParseSink is failed");
214         return;
215     }
216     if (ParseResourceDesc(json, cfg) != DH_FWK_SUCCESS) {
217         DHLOGE("ParseResourceDesc is failed");
218         return;
219     }
220 }
221 
GetCompVersionFromComConfig(const CompConfig & cCfg)222 CompVersion ComponentLoader::GetCompVersionFromComConfig(const CompConfig& cCfg)
223 {
224     CompVersion compVersions;
225     compVersions.dhType = cCfg.type;
226     compVersions.name = cCfg.name;
227     compVersions.handlerVersion = cCfg.compHandlerVersion;
228     compVersions.sinkVersion = cCfg.compSinkVersion;
229     compVersions.sourceVersion = cCfg.compSourceVersion;
230     return compVersions;
231 }
232 
CheckComponentEnable(const CompConfig & config)233 bool ComponentLoader::CheckComponentEnable(const CompConfig &config)
234 {
235     auto item = g_mapPartsParamName.find(config.type);
236     if (item == g_mapPartsParamName.end()) {
237         DHLOGI("Crrent component is enabled by default.");
238         return true;
239     }
240     bool isEnable = false;
241     if (!GetSysPara((item->second).c_str(), isEnable)) {
242         DHLOGE("sys para: %{public}s get failed.", (item->second).c_str());
243         return false;
244     }
245     DHLOGI("Component type: %{public}u, enable flag: %{public}d.", config.type, isEnable);
246     return isEnable;
247 }
248 
GetCompPathAndVersion(const std::string & jsonStr,std::map<DHType,CompConfig> & dhtypeMap)249 int32_t ComponentLoader::GetCompPathAndVersion(const std::string &jsonStr, std::map<DHType, CompConfig> &dhtypeMap)
250 {
251     if (!IsJsonLengthValid(jsonStr)) {
252         return ERR_DH_FWK_PARA_INVALID;
253     }
254     cJSON *root = cJSON_Parse(jsonStr.c_str());
255     if (root == NULL) {
256         DHLOGE("jsonStr parse failed");
257         return ERR_DH_FWK_JSON_PARSE_FAILED;
258     }
259     if (!IsArray(root, COMPONENTSLOAD_DISTRIBUTED_COMPONENTS)) {
260         DHLOGE("distributed_components is not an array");
261         cJSON_Delete(root);
262         return ERR_DH_FWK_PARA_INVALID;
263     }
264     cJSON *components = cJSON_GetObjectItem(root, COMPONENTSLOAD_DISTRIBUTED_COMPONENTS.c_str());
265 
266     size_t compSize = static_cast<size_t>(cJSON_GetArraySize(components));
267     if (compSize == 0 || compSize > MAX_COMP_SIZE) {
268         DHLOGE("CompConfig size is invalid!");
269         cJSON_Delete(root);
270         return ERR_DH_FWK_PARA_INVALID;
271     }
272     cJSON *component = nullptr;
273     cJSON_ArrayForEach(component, components) {
274         CompConfig config;
275         ParseCompConfigFromJson(component, config);
276         dhtypeMap.insert(std::pair<DHType, CompConfig>(config.type, config));
277         localDHVersion_.compVersions.insert(
278             std::pair<DHType, CompVersion>(config.type, GetCompVersionFromComConfig(config)));
279     }
280     cJSON_Delete(root);
281     isLocalVersionInit_.store(true);
282     return DH_FWK_SUCCESS;
283 }
284 
ParseCompConfigFromJson(cJSON * component,CompConfig & config)285 void ComponentLoader::ParseCompConfigFromJson(cJSON *component, CompConfig &config)
286 {
287     if (IsString(component, COMP_NAME.c_str())) {
288         config.name = cJSON_GetObjectItem(component, COMP_NAME.c_str())->valuestring;
289     }
290     if (IsString(component, COMP_TYPE.c_str())) {
291         config.type = g_mapDhTypeName[cJSON_GetObjectItem(component, COMP_TYPE.c_str())->valuestring];
292     }
293     if (IsString(component, COMP_HANDLER_LOC.c_str())) {
294         config.compHandlerLoc = cJSON_GetObjectItem(component, COMP_HANDLER_LOC.c_str())->valuestring;
295     }
296     if (IsString(component, COMP_HANDLER_VERSION.c_str())) {
297         config.compHandlerVersion = cJSON_GetObjectItem(component, COMP_HANDLER_VERSION.c_str())->valuestring;
298     }
299     if (IsString(component, COMP_SOURCE_LOC.c_str())) {
300         config.compSourceLoc = cJSON_GetObjectItem(component, COMP_SOURCE_LOC.c_str())->valuestring;
301     }
302     if (IsString(component, COMP_SOURCE_VERSION.c_str())) {
303         config.compSourceVersion = cJSON_GetObjectItem(component, COMP_SOURCE_VERSION.c_str())->valuestring;
304     }
305     if (IsInt32(component, COMP_SOURCE_SA_ID.c_str())) {
306         config.compSourceSaId =
307             static_cast<int32_t>(cJSON_GetObjectItem(component, COMP_SOURCE_SA_ID.c_str())->valuedouble);
308     }
309     if (IsString(component, COMP_SINK_LOC.c_str())) {
310         config.compSinkLoc = cJSON_GetObjectItem(component, COMP_SINK_LOC.c_str())->valuestring;
311     }
312     if (IsString(component, COMP_SINK_VERSION.c_str())) {
313         config.compSinkVersion = cJSON_GetObjectItem(component, COMP_SINK_VERSION.c_str())->valuestring;
314     }
315     if (IsInt32(component, COMP_SINK_SA_ID.c_str())) {
316         config.compSinkSaId =
317             static_cast<int32_t>(cJSON_GetObjectItem(component, COMP_SINK_SA_ID.c_str())->valuedouble);
318     }
319     if (IsArray(component, COMP_RESOURCE_DESC.c_str())) {
320         cJSON *resourceDescs = cJSON_GetObjectItem(component, COMP_RESOURCE_DESC.c_str());
321         ParseResourceDescFromJson(resourceDescs, config);
322     }
323 }
324 
ParseResourceDescFromJson(cJSON * resourceDescs,CompConfig & config)325 void ComponentLoader::ParseResourceDescFromJson(cJSON *resourceDescs, CompConfig &config)
326 {
327     cJSON *resourceDesc = nullptr;
328     cJSON_ArrayForEach(resourceDesc, resourceDescs) {
329         bool sensitiveValue;
330         cJSON *sensitive = cJSON_GetObjectItem(resourceDesc, COMP_SENSITIVE.c_str());
331         if (cJSON_IsTrue(sensitive)) {
332             sensitiveValue = true;
333         } else {
334             sensitiveValue = false;
335         }
336         ResourceDesc resource;
337         if (!IsString(resourceDesc, COMP_SUBTYPE)) {
338             DHLOGE("COMP_SUBTYPE is invalid!");
339             return;
340         }
341         resource.subtype = cJSON_GetObjectItem(resourceDesc, COMP_SUBTYPE.c_str())->valuestring;
342         resource.sensitiveValue = sensitiveValue;
343         config.compResourceDesc.push_back(resource);
344     }
345 }
346 
GetLocalDHVersion(DHVersion & dhVersion)347 int32_t ComponentLoader::GetLocalDHVersion(DHVersion &dhVersion)
348 {
349     if (!isLocalVersionInit_.load()) {
350         DHLOGE("get local DHVersion fail");
351         return ERR_DH_FWK_LOADER_GET_LOCAL_VERSION_FAIL;
352     }
353     dhVersion = localDHVersion_;
354     return DH_FWK_SUCCESS;
355 }
356 
StoreLocalDHVersionInDB()357 void ComponentLoader::StoreLocalDHVersionInDB()
358 {
359     if (!isLocalVersionInit_.load()) {
360         DHLOGE("Store local DHVersion fail");
361         return;
362     }
363     VersionInfo versionInfo;
364     versionInfo.dhVersion = VersionManager::GetInstance().GetLocalDeviceVersion();
365     versionInfo.deviceId = DHContext::GetInstance().GetDeviceInfo().deviceId;
366     versionInfo.compVersions = localDHVersion_.compVersions;
367     VersionInfoManager::GetInstance()->AddVersion(versionInfo);
368 }
369 
GetHandler(const std::string & soName)370 void *ComponentLoader::GetHandler(const std::string &soName)
371 {
372     if (soName.length() == 0 || soName.length() > PATH_MAX) {
373         DHLOGE("File canonicalization failed, soName: %{public}s", soName.c_str());
374         return nullptr;
375     }
376     void *pHandler = dlopen(soName.c_str(), RTLD_LAZY | RTLD_NODELETE);
377     if (pHandler == nullptr) {
378         DHLOGE("so: %{public}s load failed, failed reason: %{public}s", soName.c_str(), dlerror());
379         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
380             "dhfwk so open failed, soname : " + soName);
381         return nullptr;
382     }
383     return pHandler;
384 }
385 
GetAllHandler(std::map<DHType,CompConfig> & dhtypeMap)386 void ComponentLoader::GetAllHandler(std::map<DHType, CompConfig> &dhtypeMap)
387 {
388     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
389     std::map<DHType, CompConfig>::iterator itor;
390     for (itor = dhtypeMap.begin(); itor != dhtypeMap.end(); ++itor) {
391         CompHandler comHandler;
392         comHandler.type = itor->second.type;
393         comHandler.hardwareHandler = GetHandler(itor->second.compHandlerLoc);
394         comHandler.sourceHandler = GetHandler(itor->second.compSourceLoc);
395         comHandler.sourceSaId = itor->second.compSourceSaId;
396         comHandler.sinkHandler = GetHandler(itor->second.compSinkLoc);
397         comHandler.sinkSaId = itor->second.compSinkSaId;
398         std::vector<ResourceDesc> compResourceDesc = itor->second.compResourceDesc;
399         for (auto it = compResourceDesc.begin(); it != compResourceDesc.end(); it++) {
400             resDescMap_[it->subtype] = it->sensitiveValue;
401         }
402         comHandler.resourceDesc = itor->second.compResourceDesc;
403         compHandlerMap_[itor->second.type] = comHandler;
404     }
405 }
406 
GetHardwareHandler(const DHType dhType,IHardwareHandler * & hardwareHandlerPtr)407 int32_t ComponentLoader::GetHardwareHandler(const DHType dhType, IHardwareHandler *&hardwareHandlerPtr)
408 {
409     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
410     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
411         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
412         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
413     }
414 
415     if (compHandlerMap_[dhType].hardwareHandler == nullptr) {
416         DHLOGE("hardwareHandler is null.");
417         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
418     }
419 
420     GetHardwareClass getHardwareClassHandler = (GetHardwareClass)dlsym(compHandlerMap_[dhType].hardwareHandler,
421         COMPONENT_LOADER_GET_HARDWARE_HANDLER.c_str());
422     if (getHardwareClassHandler == nullptr) {
423         DHLOGE("get getHardwareClassHandler is null, failed reason : %{public}s", dlerror());
424         dlclose(compHandlerMap_[dhType].hardwareHandler);
425         compHandlerMap_[dhType].hardwareHandler = nullptr;
426         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
427     }
428     hardwareHandlerPtr = getHardwareClassHandler();
429     return DH_FWK_SUCCESS;
430 }
431 
GetSource(const DHType dhType,IDistributedHardwareSource * & sourcePtr)432 int32_t ComponentLoader::GetSource(const DHType dhType, IDistributedHardwareSource *&sourcePtr)
433 {
434     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
435     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
436         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
437         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
438     }
439 
440     if (compHandlerMap_[dhType].sourceHandler == nullptr) {
441         DHLOGE("sourceHandler is null.");
442         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
443     }
444 
445     GetSourceHardwareClass getSourceHardClassHandler = (GetSourceHardwareClass)dlsym(
446         compHandlerMap_[dhType].sourceHandler, COMPONENT_LOADER_GET_SOURCE_HANDLER.c_str());
447     if (getSourceHardClassHandler == nullptr) {
448         DHLOGE("get getSourceHardClassHandler is null, failed reason : %{public}s", dlerror());
449         dlclose(compHandlerMap_[dhType].sourceHandler);
450         compHandlerMap_[dhType].sourceHandler = nullptr;
451         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
452     }
453     sourcePtr = getSourceHardClassHandler();
454     return DH_FWK_SUCCESS;
455 }
456 
GetSink(const DHType dhType,IDistributedHardwareSink * & sinkPtr)457 int32_t ComponentLoader::GetSink(const DHType dhType, IDistributedHardwareSink *&sinkPtr)
458 {
459     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
460     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
461         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
462         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
463     }
464 
465     if (compHandlerMap_[dhType].sinkHandler == nullptr) {
466         DHLOGE("sinkHandler is null.");
467         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
468     }
469 
470     GetSinkHardwareClass getSinkHardwareClassHandler =
471         (GetSinkHardwareClass)dlsym(compHandlerMap_[dhType].sinkHandler, COMPONENT_LOADER_GET_SINK_HANDLER.c_str());
472     if (getSinkHardwareClassHandler == nullptr) {
473         DHLOGE("get getSinkHardwareClassHandler is null, failed reason : %{public}s", dlerror());
474         dlclose(compHandlerMap_[dhType].sinkHandler);
475         compHandlerMap_[dhType].sinkHandler = nullptr;
476         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
477     }
478     sinkPtr = getSinkHardwareClassHandler();
479     return DH_FWK_SUCCESS;
480 }
481 
Readfile(const std::string & filePath)482 std::string ComponentLoader::Readfile(const std::string &filePath)
483 {
484     std::ifstream infile;
485     std::string sLine;
486     std::string sAll = "";
487     infile.open(filePath);
488     if (!infile.is_open()) {
489         DHLOGE("filePath: %{public}s Readfile fail", filePath.c_str());
490         return sAll;
491     }
492 
493     while (getline(infile, sLine)) {
494         sAll.append(sLine);
495     }
496     infile.close();
497     return sAll;
498 }
499 
ParseConfig()500 int32_t ComponentLoader::ParseConfig()
501 {
502     std::map<DHType, CompConfig> dhtypeMap;
503     int32_t ret;
504     DHLOGI("ParseConfig start");
505     char buf[MAX_PATH_LEN] = {0};
506     char path[PATH_MAX + 1] = {0x00};
507     char *profilePath = GetOneCfgFile(COMPONENTSLOAD_PROFILE_PATH, buf, MAX_PATH_LEN);
508     if (profilePath == nullptr) {
509         DHLOGE("profilePath is null.");
510         return ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL;
511     }
512 
513     if (strlen(profilePath) == 0 || strlen(profilePath) > PATH_MAX || realpath(profilePath, path) == nullptr) {
514         std::string comProfilePath(profilePath);
515         DHLOGE("File connicailization failed, comProfilePath: %{public}s.", GetAnonyString(comProfilePath).c_str());
516         return ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL;
517     }
518     std::string componentProfilePath(path);
519     std::string jsonStr = Readfile(componentProfilePath);
520     if (!IsMessageLengthValid(jsonStr)) {
521         return ERR_DH_FWK_LOADER_CONFIG_JSON_INVALID;
522     }
523     ret = GetCompPathAndVersion(jsonStr, dhtypeMap);
524     if (ret != DH_FWK_SUCCESS) {
525         return ret;
526     }
527     GetAllHandler(dhtypeMap);
528     return DH_FWK_SUCCESS;
529 }
530 
ReleaseHandler(void * & handler)531 int32_t ComponentLoader::ReleaseHandler(void *&handler)
532 {
533     if (handler == nullptr) {
534         DHLOGE("handler is null.");
535         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
536     }
537 
538     if (dlclose(handler) != 0) {
539         DHLOGE("dlclose failed.");
540         return ERR_DH_FWK_LOADER_DLCLOSE_FAIL;
541     }
542     handler = nullptr;
543     return DH_FWK_SUCCESS;
544 }
545 
UnInit()546 int32_t ComponentLoader::UnInit()
547 {
548     DHLOGI("release all handler");
549     DHTraceStart(COMPONENT_RELEASE_START);
550     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
551     int32_t ret = DH_FWK_SUCCESS;
552     for (std::map<DHType, CompHandler>::iterator iter = compHandlerMap_.begin();
553         iter != compHandlerMap_.end(); ++iter) {
554         ret += ReleaseHardwareHandler(iter->first);
555         ret += ReleaseSource(iter->first);
556         ret += ReleaseSink(iter->first);
557     }
558     compHandlerMap_.clear();
559     resDescMap_.clear();
560     DHTraceEnd();
561     return ret;
562 }
563 
ReleaseHardwareHandler(const DHType dhType)564 int32_t ComponentLoader::ReleaseHardwareHandler(const DHType dhType)
565 {
566     if (!IsDHTypeExist(dhType)) {
567         return ERR_DH_FWK_TYPE_NOT_EXIST;
568     }
569     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].hardwareHandler);
570     if (ret) {
571         DHLOGE("fail, dhType: %{public}#X", dhType);
572         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
573             dhType, ret, "dhfwk release hardware handler failed.");
574     }
575     return ret;
576 }
577 
ReleaseSource(const DHType dhType)578 int32_t ComponentLoader::ReleaseSource(const DHType dhType)
579 {
580     if (!IsDHTypeExist(dhType)) {
581         return ERR_DH_FWK_TYPE_NOT_EXIST;
582     }
583     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sourceHandler);
584     if (ret) {
585         DHLOGE("fail, dhType: %{public}#X", dhType);
586         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
587             dhType, ret, "dhfwk release source failed.");
588     }
589     return ret;
590 }
591 
ReleaseSink(const DHType dhType)592 int32_t ComponentLoader::ReleaseSink(const DHType dhType)
593 {
594     if (!IsDHTypeExist(dhType)) {
595         return ERR_DH_FWK_TYPE_NOT_EXIST;
596     }
597     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sinkHandler);
598     if (ret) {
599         DHLOGE("fail, dhType: %{public}#X", dhType);
600         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
601             dhType, ret, "dhfwk release sink failed.");
602     }
603     return ret;
604 }
605 
IsDHTypeExist(DHType dhType)606 bool ComponentLoader::IsDHTypeExist(DHType dhType)
607 {
608     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
609         DHLOGE("fail, dhType: %{public}#X not exist", dhType);
610         return false;
611     }
612     return true;
613 }
614 
GetSourceSaId(const DHType dhType)615 int32_t ComponentLoader::GetSourceSaId(const DHType dhType)
616 {
617     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
618     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
619         DHLOGE("DHType not exist, dhType: %{public}" PRIu32, (uint32_t)dhType);
620         return DEFAULT_SA_ID;
621     }
622     return compHandlerMap_[dhType].sourceSaId;
623 }
624 
GetDHTypeBySrcSaId(const int32_t saId)625 DHType ComponentLoader::GetDHTypeBySrcSaId(const int32_t saId)
626 {
627     std::lock_guard<std::mutex> lock(compHandlerMapMutex_);
628     DHType type = DHType::UNKNOWN;
629     for (const auto &handler : compHandlerMap_) {
630         if (handler.second.sourceSaId == saId) {
631             type = handler.second.type;
632             break;
633         }
634     }
635     return type;
636 }
637 
GetCompResourceDesc()638 std::map<std::string, bool> ComponentLoader::GetCompResourceDesc()
639 {
640     return resDescMap_;
641 }
642 } // namespace DistributedHardware
643 } // namespace OHOS
644