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