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