1 /*
2 * Copyright (c) 2021 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 <dlfcn.h>
19 #include <fstream>
20 #include <string>
21
22 #include "nlohmann/json.hpp"
23
24 #include "constants.h"
25 #include "distributed_hardware_log.h"
26
27 using nlohmann::json;
28
29 namespace OHOS {
30 namespace DistributedHardware {
31 #undef DH_LOG_TAG
32 #define DH_LOG_TAG "ComponentLoader"
33
34 IMPLEMENT_SINGLE_INSTANCE(ComponentLoader);
35 using GetHardwareClass = IHardwareHandler *(*)();
36 using GetSourceHardwareClass = IDistributedHardwareSource *(*)();
37 using GetSinkHardwareClass = IDistributedHardwareSink *(*)();
38 namespace {
39 const std::string DEFAULT_NAME = "";
40 const std::string DEFAULT_HANDLER_LOC = "";
41 const std::string DEFAULT_SOURCE_LOC = "";
42 const std::string DEFAULT_SINK_LOC = "";
43 const std::string DEFAULT_TYPE = "UNKNOWN";
44 const std::string DEFAULT_VERSION = "1.0";
45 }
46 std::map<std::string, DHType> g_mapDhTypeName = {
47 { "UNKNOWN", DHType::UNKNOWN },
48 { "CAMERA", DHType::CAMERA },
49 { "MIC", DHType::MIC },
50 { "SPEAKER", DHType::SPEAKER },
51 { "DISPLAY", DHType::DISPLAY },
52 { "GPS", DHType::GPS },
53 { "BUTTON", DHType::BUTTON },
54 { "HFP", DHType::HFP },
55 { "A2D", DHType::A2D },
56 { "VIRMODEM_MIC", DHType::VIRMODEM_MIC },
57 { "VIRMODEM_SPEAKER", DHType::VIRMODEM_SPEAKER },
58 };
59
Init()60 int32_t ComponentLoader::Init()
61 {
62 return ParseConfig();
63 }
64
GetAllCompTypes()65 std::vector<DHType> ComponentLoader::GetAllCompTypes()
66 {
67 std::vector<DHType> DHTypeALL;
68 for (std::map<DHType, CompHandler>::iterator it = compHandlerMap_.begin(); it != compHandlerMap_.end(); it++) {
69 DHTypeALL.push_back(it->first);
70 }
71 return DHTypeALL;
72 }
73
from_json(const nlohmann::json & j,CompConfig & cCfg)74 void from_json(const nlohmann::json &j, CompConfig &cCfg)
75 {
76 cCfg.name = j.value("name", DEFAULT_NAME);
77 cCfg.type = g_mapDhTypeName[j.value("type", DEFAULT_TYPE)];
78 cCfg.compHandlerLoc = j.value("comp_handler_loc", DEFAULT_HANDLER_LOC);
79 cCfg.compHandlerVersion = j.value("comp_handler_version", DEFAULT_VERSION);
80 cCfg.compSourceLoc = j.value("comp_source_loc", DEFAULT_SOURCE_LOC);
81 cCfg.compSourceVersion = j.value("comp_source_version", DEFAULT_VERSION);
82 cCfg.compSinkLoc = j.value("comp_sink_loc", DEFAULT_SINK_LOC);
83 cCfg.compSinkVersion = j.value("comp_sink_version", DEFAULT_VERSION);
84 }
85
GetCompVersionFromComConfig(const CompConfig & cCfg)86 CompVersion ComponentLoader::GetCompVersionFromComConfig(const CompConfig& cCfg)
87 {
88 CompVersion compVersions;
89 compVersions.dhType = cCfg.type;
90 compVersions.name = cCfg.name;
91 compVersions.handlerVersion = cCfg.compHandlerVersion;
92 compVersions.sinkVersion = cCfg.compSinkVersion;
93 compVersions.sourceVersion = cCfg.compSourceVersion;
94 return compVersions;
95 }
96
GetCompPathAndVersion(const std::string & jsonStr,std::map<DHType,CompConfig> & dhtypeMap)97 int32_t ComponentLoader::GetCompPathAndVersion(const std::string &jsonStr, std::map<DHType, CompConfig> &dhtypeMap)
98 {
99 auto jsonCfg = json::parse(jsonStr);
100 if (jsonCfg.find(COMPONENTSLOAD_DISTRIBUTED_COMPONENTS) == jsonCfg.end()) {
101 DHLOGE("not find distributed_components");
102 return ERR_DH_FWK_PARA_INVALID;
103 }
104
105 std::vector<CompConfig> vecJsnCfg =
106 jsonCfg.at(COMPONENTSLOAD_DISTRIBUTED_COMPONENTS).get<std::vector<CompConfig>>();
107 DHLOGI("get distributed_components CompConfig size is %d", vecJsnCfg.size());
108 for (std::vector<CompConfig>::iterator iter = vecJsnCfg.begin(); iter != vecJsnCfg.end(); iter++) {
109 dhtypeMap.insert(std::pair<DHType, CompConfig>((*iter).type, (*iter)));
110 localDHVersion_.compVersions.insert(
111 std::pair<DHType, CompVersion>((*iter).type, GetCompVersionFromComConfig(*iter)));
112 }
113 isLocalVersionInit_.store(true);
114 return DH_FWK_SUCCESS;
115 }
116
GetLocalDHVersion(DHVersion & dhVersion)117 int32_t ComponentLoader::GetLocalDHVersion(DHVersion &dhVersion)
118 {
119 if (!isLocalVersionInit_.load()) {
120 DHLOGE("get local DHVersion fail");
121 return ERR_DH_FWK_LOADER_GET_LOCAL_VERSION_FAIL;
122 }
123 dhVersion = localDHVersion_;
124 return DH_FWK_SUCCESS;
125 }
126
GetHandler(const std::string & soName)127 void *ComponentLoader::GetHandler(const std::string &soName)
128 {
129 if (soName.length() <= 0) {
130 DHLOGE("%s soName length is 0", soName.c_str());
131 return nullptr;
132 }
133 char path[PATH_MAX + 1] = {0x00};
134 if (soName.length() == 0 || soName.length() > PATH_MAX || realpath(soName.c_str(), path) == NULL) {
135 DHLOGE("File canonicalization failed");
136 return nullptr;
137 }
138 void *pHandler = dlopen(path, RTLD_LAZY | RTLD_NODELETE);
139 if (pHandler == nullptr) {
140 DHLOGE("%s handler load failed.", path);
141 return nullptr;
142 }
143 return pHandler;
144 }
145
GetAllHandler(std::map<DHType,CompConfig> & dhtypeMap)146 void ComponentLoader::GetAllHandler(std::map<DHType, CompConfig> &dhtypeMap)
147 {
148 std::map<DHType, CompConfig>::iterator itor;
149 for (itor = dhtypeMap.begin(); itor != dhtypeMap.end(); itor++) {
150 CompHandler comHandler;
151 comHandler.hardwareHandler = GetHandler(itor->second.compHandlerLoc);
152 comHandler.sinkHandler = GetHandler(itor->second.compSinkLoc);
153 comHandler.sourceHandler = GetHandler(itor->second.compSourceLoc);
154 compHandlerMap_.insert(std::pair<DHType, CompHandler>(itor->second.type, comHandler));
155 }
156 }
157
GetHardwareHandler(const DHType dhType,IHardwareHandler * & hardwareHandlerPtr)158 int32_t ComponentLoader::GetHardwareHandler(const DHType dhType, IHardwareHandler *&hardwareHandlerPtr)
159 {
160 if (compHandlerMap_[dhType].hardwareHandler == nullptr) {
161 DHLOGE("hardwareHandler is null.");
162 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
163 }
164
165 GetHardwareClass getHardwareClassHandler = (GetHardwareClass)dlsym(compHandlerMap_[dhType].hardwareHandler,
166 COMPONENT_LOADER_GET_HARDWARE_HANDLER.c_str());
167 if (getHardwareClassHandler == nullptr) {
168 DHLOGE("get getHardwareClassHandler is null.");
169 dlclose(compHandlerMap_[dhType].hardwareHandler);
170 compHandlerMap_[dhType].hardwareHandler = nullptr;
171 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
172 }
173 hardwareHandlerPtr = getHardwareClassHandler();
174 return DH_FWK_SUCCESS;
175 }
176
GetSource(const DHType dhType,IDistributedHardwareSource * & sourcePtr)177 int32_t ComponentLoader::GetSource(const DHType dhType, IDistributedHardwareSource *&sourcePtr)
178 {
179 if (compHandlerMap_[dhType].sourceHandler == nullptr) {
180 DHLOGE("sourceHandler is null.");
181 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
182 }
183
184 GetSourceHardwareClass getSourceHardClassHandler = (GetSourceHardwareClass)dlsym(
185 compHandlerMap_[dhType].sourceHandler, COMPONENT_LOADER_GET_SOURCE_HANDLER.c_str());
186 if (getSourceHardClassHandler == nullptr) {
187 DHLOGE("get getSourceHardClassHandler is null.");
188 dlclose(compHandlerMap_[dhType].sourceHandler);
189 compHandlerMap_[dhType].sourceHandler = nullptr;
190 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
191 }
192 sourcePtr = getSourceHardClassHandler();
193 return DH_FWK_SUCCESS;
194 }
195
GetSink(const DHType dhType,IDistributedHardwareSink * & sinkPtr)196 int32_t ComponentLoader::GetSink(const DHType dhType, IDistributedHardwareSink *&sinkPtr)
197 {
198 if (compHandlerMap_[dhType].sinkHandler == nullptr) {
199 DHLOGE("sinkHandler is null.");
200 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
201 }
202
203 GetSinkHardwareClass getSinkHardwareClassHandler =
204 (GetSinkHardwareClass)dlsym(compHandlerMap_[dhType].sinkHandler, COMPONENT_LOADER_GET_SINK_HANDLER.c_str());
205 if (getSinkHardwareClassHandler == nullptr) {
206 DHLOGE("get getSinkHardwareClassHandler is null.");
207 dlclose(compHandlerMap_[dhType].sinkHandler);
208 compHandlerMap_[dhType].sinkHandler = nullptr;
209 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
210 }
211 sinkPtr = getSinkHardwareClassHandler();
212 return DH_FWK_SUCCESS;
213 }
214
Readfile(const std::string & filePath)215 std::string ComponentLoader::Readfile(const std::string &filePath)
216 {
217 std::ifstream infile;
218 std::string sLine;
219 std::string sAll = "";
220 infile.open(filePath);
221 if (!infile.is_open()) {
222 DHLOGE("filePath: %s Readfile fail", filePath.c_str());
223 return sAll;
224 }
225
226 while (getline(infile, sLine)) {
227 sAll.append(sLine);
228 }
229 infile.close();
230 return sAll;
231 }
232
ParseConfig()233 int32_t ComponentLoader::ParseConfig()
234 {
235 std::map<DHType, CompConfig> dhtypeMap;
236 int32_t ret;
237 DHLOGI("ParseConfig start");
238 std::string jsonStr = Readfile(COMPONENTSLOAD_PROFILE_PATH);
239 if (jsonStr.length() == 0) {
240 DHLOGE("profile is empty return");
241 return ERR_DH_FWK_LOADER_COMPONENT_PROFILE_IS_EMPTY;
242 }
243 ret = GetCompPathAndVersion(jsonStr, dhtypeMap);
244 GetAllHandler(dhtypeMap);
245 return ret;
246 }
247
ReleaseHandler(void * & handler)248 int32_t ComponentLoader::ReleaseHandler(void *&handler)
249 {
250 if (handler == nullptr) {
251 DHLOGE("handler is null.");
252 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
253 }
254
255 if (dlclose(handler) != 0) {
256 DHLOGE("dlclose failed.");
257 return ERR_DH_FWK_LOADER_DLCLOSE_FAIL;
258 }
259 handler = nullptr;
260 return DH_FWK_SUCCESS;
261 }
262
UnInit()263 int32_t ComponentLoader::UnInit()
264 {
265 DHLOGI("release all handler");
266 int32_t ret = DH_FWK_SUCCESS;
267 for (std::map<DHType, CompHandler>::iterator iter = compHandlerMap_.begin();
268 iter != compHandlerMap_.end(); iter++) {
269 ret += ReleaseHardwareHandler(iter->first);
270 ret += ReleaseSource(iter->first);
271 ret += ReleaseSink(iter->first);
272 }
273 compHandlerMap_.clear();
274 return ret;
275 }
276
ReleaseHardwareHandler(const DHType dhType)277 int32_t ComponentLoader::ReleaseHardwareHandler(const DHType dhType)
278 {
279 if (!IsDHTypeExist(dhType)) {
280 return ERR_DH_FWK_TYPE_NOT_EXIST;
281 }
282 int32_t ret = ReleaseHandler(compHandlerMap_[dhType].hardwareHandler);
283 if (ret) {
284 DHLOGE("fail, dhType: %#X", dhType);
285 }
286 return ret;
287 }
288
ReleaseSource(const DHType dhType)289 int32_t ComponentLoader::ReleaseSource(const DHType dhType)
290 {
291 if (!IsDHTypeExist(dhType)) {
292 return ERR_DH_FWK_TYPE_NOT_EXIST;
293 }
294 int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sourceHandler);
295 if (ret) {
296 DHLOGE("fail, dhType: %#X", dhType);
297 }
298 return ret;
299 }
300
ReleaseSink(const DHType dhType)301 int32_t ComponentLoader::ReleaseSink(const DHType dhType)
302 {
303 if (!IsDHTypeExist(dhType)) {
304 return ERR_DH_FWK_TYPE_NOT_EXIST;
305 }
306 int32_t ret = ReleaseHandler(compHandlerMap_[dhType].sinkHandler);
307 if (ret) {
308 DHLOGE("fail, dhType: %#X", dhType);
309 }
310 return ret;
311 }
312
IsDHTypeExist(DHType dhType)313 bool ComponentLoader::IsDHTypeExist(DHType dhType)
314 {
315 if (compHandlerMap_.find(dhType) == compHandlerMap_.end()) {
316 DHLOGE("fail, dhType: %#X not exist", dhType);
317 return false;
318 }
319 return true;
320 }
321 }
322 }