• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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 #include "nlohmann/json.hpp"
25 
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 using nlohmann::json;
38 
39 namespace OHOS {
40 namespace DistributedHardware {
41 #undef DH_LOG_TAG
42 #define DH_LOG_TAG "ComponentLoader"
43 
44 IMPLEMENT_SINGLE_INSTANCE(ComponentLoader);
45 using GetHardwareClass = IHardwareHandler *(*)();
46 using GetSourceHardwareClass = IDistributedHardwareSource *(*)();
47 using GetSinkHardwareClass = IDistributedHardwareSink *(*)();
48 namespace {
49 const std::string COMP_NAME = "name";
50 const std::string COMP_TYPE = "type";
51 const std::string COMP_HANDLER_LOC = "comp_handler_loc";
52 const std::string COMP_HANDLER_VERSION = "comp_handler_version";
53 const std::string COMP_SOURCE_LOC = "comp_source_loc";
54 const std::string COMP_SOURCE_VERSION = "comp_source_version";
55 const std::string COMP_SOURCE_SA_ID = "comp_source_sa_id";
56 const std::string COMP_SINK_LOC = "comp_sink_loc";
57 const std::string COMP_SINK_VERSION = "comp_sink_version";
58 const std::string COMP_SINK_SA_ID = "comp_sink_sa_id";
59 
60 const std::string COMPONENTSLOAD_DISTRIBUTED_COMPONENTS = "distributed_components";
61 
62 const std::string DEFAULT_NAME = "";
63 const std::string DEFAULT_TYPE = "UNKNOWN";
64 const std::string DEFAULT_LOC = "";
65 const int32_t DEFAULT_SA_ID = -1;
66 const std::string DEFAULT_VERSION = "1.0";
67 
68 #ifdef __LP64__
69 const std::string LIB_LOAD_PATH = "/system/lib64/";
70 #else
71 const std::string LIB_LOAD_PATH = "/system/lib/";
72 #endif
73 
74 std::map<std::string, DHType> g_mapDhTypeName = {
75     { "UNKNOWN", DHType::UNKNOWN },
76     { "CAMERA", DHType::CAMERA },
77     { "AUDIO", DHType::AUDIO },
78     { "SCREEN", DHType::SCREEN },
79     { "GPS", DHType::GPS },
80     { "INPUT", DHType::INPUT },
81     { "HFP", DHType::HFP },
82     { "A2D", DHType::A2D },
83     { "VIRMODEM_MIC", DHType::VIRMODEM_MIC },
84     { "VIRMODEM_SPEAKER", DHType::VIRMODEM_SPEAKER },
85 };
86 }
87 
Init()88 int32_t ComponentLoader::Init()
89 {
90     DHLOGI("start");
91     DHTraceStart(COMPONENT_LOAD_START);
92     int32_t ret = ParseConfig();
93     StoreLocalDHVersionInDB();
94     DHTraceEnd();
95 
96     return ret;
97 }
98 
GetAllCompTypes()99 std::vector<DHType> ComponentLoader::GetAllCompTypes()
100 {
101     std::vector<DHType> DHTypeALL;
102     for (std::map<DHType, CompHandler>::iterator it = compHandlerMap_.begin(); it != compHandlerMap_.end(); ++it) {
103         DHTypeALL.push_back(it->first);
104     }
105     return DHTypeALL;
106 }
107 
from_json(const nlohmann::json & json,CompConfig & cfg)108 void from_json(const nlohmann::json &json, CompConfig &cfg)
109 {
110     if (!IsString(json, COMP_NAME)) {
111         DHLOGE("COMP_NAME is invalid");
112         return;
113     }
114     cfg.name = json.at(COMP_NAME).get<std::string>();
115     if (!IsString(json, COMP_TYPE)) {
116         DHLOGE("COMP_TYPE is invalid");
117         return;
118     }
119     cfg.type = g_mapDhTypeName[json.at(COMP_TYPE).get<std::string>()];
120     if (!IsString(json, COMP_HANDLER_LOC)) {
121         DHLOGE("COMP_HANDLER_LOC is invalid");
122         return;
123     }
124     cfg.compHandlerLoc = json.at(COMP_HANDLER_LOC).get<std::string>();
125     if (!IsString(json, COMP_HANDLER_VERSION)) {
126         DHLOGE("COMP_HANDLER_VERSION is invalid");
127         return;
128     }
129     cfg.compHandlerVersion = json.at(COMP_HANDLER_VERSION).get<std::string>();
130     if (!IsString(json, COMP_SOURCE_LOC)) {
131         DHLOGE("COMP_SOURCE_LOC is invalid");
132         return;
133     }
134     cfg.compSourceLoc = json.at(COMP_SOURCE_LOC).get<std::string>();
135     if (!IsString(json, COMP_SOURCE_VERSION)) {
136         DHLOGE("COMP_SOURCE_VERSION is invalid");
137         return;
138     }
139     cfg.compSourceVersion = json.at(COMP_SOURCE_VERSION).get<std::string>();
140     if (!IsInt32(json, COMP_SOURCE_SA_ID)) {
141         DHLOGE("COMP_SOURCE_SA_ID is invalid");
142         return;
143     }
144     cfg.compSourceSaId = json.at(COMP_SOURCE_SA_ID).get<int32_t>();
145     if (!IsString(json, COMP_SINK_LOC)) {
146         DHLOGE("COMP_SINK_LOC is invalid");
147         return;
148     }
149     cfg.compSinkLoc = json.at(COMP_SINK_LOC).get<std::string>();
150     if (!IsString(json, COMP_SINK_VERSION)) {
151         DHLOGE("COMP_SINK_VERSION is invalid");
152         return;
153     }
154     cfg.compSinkVersion = json.at(COMP_SINK_VERSION).get<std::string>();
155     if (!IsInt32(json, COMP_SINK_SA_ID)) {
156         DHLOGE("COMP_SINK_SA_ID is invalid");
157         return;
158     }
159     cfg.compSinkSaId = json.at(COMP_SINK_SA_ID).get<int32_t>();
160 }
161 
GetCompVersionFromComConfig(const CompConfig & cCfg)162 CompVersion ComponentLoader::GetCompVersionFromComConfig(const CompConfig& cCfg)
163 {
164     CompVersion compVersions;
165     compVersions.dhType = cCfg.type;
166     compVersions.name = cCfg.name;
167     compVersions.handlerVersion = cCfg.compHandlerVersion;
168     compVersions.sinkVersion = cCfg.compSinkVersion;
169     compVersions.sourceVersion = cCfg.compSourceVersion;
170     return compVersions;
171 }
172 
GetCompPathAndVersion(const std::string & jsonStr,std::map<DHType,CompConfig> & dhtypeMap)173 int32_t ComponentLoader::GetCompPathAndVersion(const std::string &jsonStr, std::map<DHType, CompConfig> &dhtypeMap)
174 {
175     auto jsonCfg = json::parse(jsonStr, nullptr, false);
176     if (jsonCfg.is_discarded()) {
177         DHLOGE("jsonStr parse failed");
178         return ERR_DH_FWK_JSON_PARSE_FAILED;
179     }
180 
181     if (jsonCfg.find(COMPONENTSLOAD_DISTRIBUTED_COMPONENTS) == jsonCfg.end()) {
182         DHLOGE("not find distributed_components");
183         return ERR_DH_FWK_PARA_INVALID;
184     }
185 
186     std::vector<CompConfig> vecJsnCfg =
187         jsonCfg.at(COMPONENTSLOAD_DISTRIBUTED_COMPONENTS).get<std::vector<CompConfig>>();
188     DHLOGI("get distributed_components CompConfig size is %d", vecJsnCfg.size());
189     if (vecJsnCfg.size() == 0 || vecJsnCfg.size() > MAX_COMP_SIZE) {
190         DHLOGE("CompConfig size is invalid!");
191         return ERR_DH_FWK_PARA_INVALID;
192     }
193     for (auto iter = vecJsnCfg.begin(); iter != vecJsnCfg.end(); ++iter) {
194         dhtypeMap.insert(std::pair<DHType, CompConfig>((*iter).type, (*iter)));
195         localDHVersion_.compVersions.insert(
196             std::pair<DHType, CompVersion>((*iter).type, GetCompVersionFromComConfig(*iter)));
197     }
198     isLocalVersionInit_.store(true);
199     return DH_FWK_SUCCESS;
200 }
201 
GetLocalDHVersion(DHVersion & dhVersion)202 int32_t ComponentLoader::GetLocalDHVersion(DHVersion &dhVersion)
203 {
204     if (!isLocalVersionInit_.load()) {
205         DHLOGE("get local DHVersion fail");
206         return ERR_DH_FWK_LOADER_GET_LOCAL_VERSION_FAIL;
207     }
208     dhVersion = localDHVersion_;
209     return DH_FWK_SUCCESS;
210 }
211 
StoreLocalDHVersionInDB()212 void ComponentLoader::StoreLocalDHVersionInDB()
213 {
214     if (!isLocalVersionInit_.load()) {
215         DHLOGE("Store local DHVersion fail");
216         return;
217     }
218     VersionInfo versionInfo;
219     versionInfo.dhVersion = VersionManager::GetInstance().GetLocalDeviceVersion();
220     versionInfo.deviceId = DHContext::GetInstance().GetDeviceInfo().deviceId;
221     versionInfo.compVersions = localDHVersion_.compVersions;
222     VersionInfoManager::GetInstance()->AddVersion(versionInfo);
223 }
224 
GetHandler(const std::string & soName)225 void *ComponentLoader::GetHandler(const std::string &soName)
226 {
227     char path[PATH_MAX + 1] = {0x00};
228     if (soName.length() == 0 || (LIB_LOAD_PATH.length() + soName.length()) > PATH_MAX ||
229         realpath((LIB_LOAD_PATH + soName).c_str(), path) == nullptr) {
230         DHLOGE("File canonicalization failed");
231         return nullptr;
232     }
233     void *pHandler = dlopen(path, RTLD_LAZY | RTLD_NODELETE);
234     if (pHandler == nullptr) {
235         DHLOGE("%s handler load failed, failed reason : %s", path, dlerror());
236         HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
237             "dhfwk so open failed, soname : " + soName);
238         return nullptr;
239     }
240     return pHandler;
241 }
242 
GetAllHandler(std::map<DHType,CompConfig> & dhtypeMap)243 void ComponentLoader::GetAllHandler(std::map<DHType, CompConfig> &dhtypeMap)
244 {
245     std::map<DHType, CompConfig>::iterator itor;
246     for (itor = dhtypeMap.begin(); itor != dhtypeMap.end(); ++itor) {
247         CompHandler comHandler;
248         comHandler.type = itor->second.type;
249         comHandler.hardwareHandler = GetHandler(itor->second.compHandlerLoc);
250         comHandler.sourceHandler = GetHandler(itor->second.compSourceLoc);
251         comHandler.sourceSaId = itor->second.compSourceSaId;
252         comHandler.sinkHandler = GetHandler(itor->second.compSinkLoc);
253         comHandler.sinkSaId = itor->second.compSinkSaId;
254         compHandlerMap_[itor->second.type] = comHandler;
255     }
256 }
257 
GetHardwareHandler(const DHType dhType,IHardwareHandler * & hardwareHandlerPtr)258 int32_t ComponentLoader::GetHardwareHandler(const DHType dhType, IHardwareHandler *&hardwareHandlerPtr)
259 {
260     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
261         DHLOGE("DHType not exist, dhType: %" PRIu32, (uint32_t)dhType);
262         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
263     }
264 
265     if (compHandlerMap_[dhType].hardwareHandler == nullptr) {
266         DHLOGE("hardwareHandler is null.");
267         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
268     }
269 
270     GetHardwareClass getHardwareClassHandler = (GetHardwareClass)dlsym(compHandlerMap_[dhType].hardwareHandler,
271         COMPONENT_LOADER_GET_HARDWARE_HANDLER.c_str());
272     if (getHardwareClassHandler == nullptr) {
273         DHLOGE("get getHardwareClassHandler is null, failed reason : %s", dlerror());
274         dlclose(compHandlerMap_[dhType].hardwareHandler);
275         compHandlerMap_[dhType].hardwareHandler = nullptr;
276         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
277     }
278     hardwareHandlerPtr = getHardwareClassHandler();
279     return DH_FWK_SUCCESS;
280 }
281 
GetSource(const DHType dhType,IDistributedHardwareSource * & sourcePtr)282 int32_t ComponentLoader::GetSource(const DHType dhType, IDistributedHardwareSource *&sourcePtr)
283 {
284     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
285         DHLOGE("DHType not exist, dhType: %" PRIu32, (uint32_t)dhType);
286         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
287     }
288 
289     if (compHandlerMap_[dhType].sourceHandler == nullptr) {
290         DHLOGE("sourceHandler is null.");
291         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
292     }
293 
294     GetSourceHardwareClass getSourceHardClassHandler = (GetSourceHardwareClass)dlsym(
295         compHandlerMap_[dhType].sourceHandler, COMPONENT_LOADER_GET_SOURCE_HANDLER.c_str());
296     if (getSourceHardClassHandler == nullptr) {
297         DHLOGE("get getSourceHardClassHandler is null, failed reason : %s", dlerror());
298         dlclose(compHandlerMap_[dhType].sourceHandler);
299         compHandlerMap_[dhType].sourceHandler = nullptr;
300         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
301     }
302     sourcePtr = getSourceHardClassHandler();
303     return DH_FWK_SUCCESS;
304 }
305 
GetSink(const DHType dhType,IDistributedHardwareSink * & sinkPtr)306 int32_t ComponentLoader::GetSink(const DHType dhType, IDistributedHardwareSink *&sinkPtr)
307 {
308     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
309         DHLOGE("DHType not exist, dhType: %" PRIu32, (uint32_t)dhType);
310         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
311     }
312 
313     if (compHandlerMap_[dhType].sinkHandler == nullptr) {
314         DHLOGE("sinkHandler is null.");
315         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
316     }
317 
318     GetSinkHardwareClass getSinkHardwareClassHandler =
319         (GetSinkHardwareClass)dlsym(compHandlerMap_[dhType].sinkHandler, COMPONENT_LOADER_GET_SINK_HANDLER.c_str());
320     if (getSinkHardwareClassHandler == nullptr) {
321         DHLOGE("get getSinkHardwareClassHandler is null, failed reason : %s", dlerror());
322         dlclose(compHandlerMap_[dhType].sinkHandler);
323         compHandlerMap_[dhType].sinkHandler = nullptr;
324         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
325     }
326     sinkPtr = getSinkHardwareClassHandler();
327     return DH_FWK_SUCCESS;
328 }
329 
Readfile(const std::string & filePath)330 std::string ComponentLoader::Readfile(const std::string &filePath)
331 {
332     std::ifstream infile;
333     std::string sLine;
334     std::string sAll = "";
335     infile.open(filePath);
336     if (!infile.is_open()) {
337         DHLOGE("filePath: %s Readfile fail", filePath.c_str());
338         return sAll;
339     }
340 
341     while (getline(infile, sLine)) {
342         sAll.append(sLine);
343     }
344     infile.close();
345     return sAll;
346 }
347 
ParseConfig()348 int32_t ComponentLoader::ParseConfig()
349 {
350     std::map<DHType, CompConfig> dhtypeMap;
351     int32_t ret;
352     DHLOGI("ParseConfig start");
353     char buf[MAX_PATH_LEN] = {0};
354     char path[PATH_MAX + 1] = {0x00};
355     char *profilePath = GetOneCfgFile(COMPONENTSLOAD_PROFILE_PATH, buf, MAX_PATH_LEN);
356     if (profilePath == nullptr) {
357         DHLOGE("profilePath is null.");
358         return ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL;
359     }
360     if (strlen(profilePath) == 0 || strlen(profilePath) > PATH_MAX || realpath(profilePath, path) == nullptr) {
361         DHLOGE("File connicailization failed.");
362         return ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL;
363     }
364     std::string componentProfilePath(path);
365     std::string jsonStr = Readfile(componentProfilePath);
366     if (jsonStr.length() == 0 || jsonStr.size() > MAX_MESSAGE_LEN) {
367         DHLOGE("ConfigJson size is invalid!");
368         return ERR_DH_FWK_LOADER_CONFIG_JSON_INVALID;
369     }
370     ret = GetCompPathAndVersion(jsonStr, dhtypeMap);
371     if (ret != DH_FWK_SUCCESS) {
372         return ret;
373     }
374     GetAllHandler(dhtypeMap);
375     return DH_FWK_SUCCESS;
376 }
377 
ReleaseHandler(void * & handler)378 int32_t ComponentLoader::ReleaseHandler(void *&handler)
379 {
380     if (handler == nullptr) {
381         DHLOGE("handler is null.");
382         return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
383     }
384 
385     if (dlclose(handler) != 0) {
386         DHLOGE("dlclose failed.");
387         return ERR_DH_FWK_LOADER_DLCLOSE_FAIL;
388     }
389     handler = nullptr;
390     return DH_FWK_SUCCESS;
391 }
392 
UnInit()393 int32_t ComponentLoader::UnInit()
394 {
395     DHLOGI("release all handler");
396     DHTraceStart(COMPONENT_RELEASE_START);
397     int32_t ret = DH_FWK_SUCCESS;
398     for (std::map<DHType, CompHandler>::iterator iter = compHandlerMap_.begin();
399         iter != compHandlerMap_.end(); ++iter) {
400         ret += ReleaseHardwareHandler(iter->first);
401         ret += ReleaseSource(iter->first);
402         ret += ReleaseSink(iter->first);
403     }
404     compHandlerMap_.clear();
405     DHTraceEnd();
406     return ret;
407 }
408 
ReleaseHardwareHandler(const DHType dhType)409 int32_t ComponentLoader::ReleaseHardwareHandler(const DHType dhType)
410 {
411     if (!IsDHTypeExist(dhType)) {
412         return ERR_DH_FWK_TYPE_NOT_EXIST;
413     }
414     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].hardwareHandler);
415     if (ret) {
416         DHLOGE("fail, dhType: %#X", dhType);
417         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
418             dhType, ret, "dhfwk release hardware handler failed.");
419     }
420     return ret;
421 }
422 
ReleaseSource(const DHType dhType)423 int32_t ComponentLoader::ReleaseSource(const DHType dhType)
424 {
425     if (!IsDHTypeExist(dhType)) {
426         return ERR_DH_FWK_TYPE_NOT_EXIST;
427     }
428     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sourceHandler);
429     if (ret) {
430         DHLOGE("fail, dhType: %#X", dhType);
431         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
432             dhType, ret, "dhfwk release source failed.");
433     }
434     return ret;
435 }
436 
ReleaseSink(const DHType dhType)437 int32_t ComponentLoader::ReleaseSink(const DHType dhType)
438 {
439     if (!IsDHTypeExist(dhType)) {
440         return ERR_DH_FWK_TYPE_NOT_EXIST;
441     }
442     int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sinkHandler);
443     if (ret) {
444         DHLOGE("fail, dhType: %#X", dhType);
445         HiSysEventWriteReleaseMsg(DHFWK_RELEASE_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
446             dhType, ret, "dhfwk release sink failed.");
447     }
448     return ret;
449 }
450 
IsDHTypeExist(DHType dhType)451 bool ComponentLoader::IsDHTypeExist(DHType dhType)
452 {
453     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
454         DHLOGE("fail, dhType: %#X not exist", dhType);
455         return false;
456     }
457     return true;
458 }
459 
GetSourceSaId(const DHType dhType)460 int32_t ComponentLoader::GetSourceSaId(const DHType dhType)
461 {
462     if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
463         DHLOGE("DHType not exist, dhType: %" PRIu32, (uint32_t)dhType);
464         return DEFAULT_SA_ID;
465     }
466     return compHandlerMap_[dhType].sourceSaId;
467 }
468 
GetDHTypeBySrcSaId(const int32_t saId)469 DHType ComponentLoader::GetDHTypeBySrcSaId(const int32_t saId)
470 {
471     DHType type = DHType::UNKNOWN;
472     for (const auto &handler : compHandlerMap_) {
473         if (handler.second.sourceSaId == saId) {
474             type = handler.second.type;
475             break;
476         }
477     }
478     return type;
479 }
480 } // namespace DistributedHardware
481 } // namespace OHOS
482