• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }