• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "extension_plugin_info.h"
17 
18 #include <dirent.h>
19 #include <dlfcn.h>
20 #include <unistd.h>
21 
22 #include "extension_module_loader.h"
23 #include "file_path_utils.h"
24 #include "hilog_wrapper.h"
25 
26 namespace OHOS {
27 namespace AbilityRuntime {
28 #ifdef APP_USE_ARM64
29 const std::string EXTENSION_LIB = "system/lib64/extensionability";
30 #else
31 const std::string EXTENSION_LIB = "system/lib/extensionability";
32 #endif
33 const std::string PATH_SEPARATOR = "/";
34 const std::string LIB_TYPE = ".so";
35 constexpr char EXTENSION_PARAMS_TYPE[] = "type";
36 constexpr char EXTENSION_PARAMS_NAME[] = "name";
37 
ExtensionPluginInfo()38 ExtensionPluginInfo::ExtensionPluginInfo()
39 {
40 }
41 
GetInstance()42 ExtensionPluginInfo& ExtensionPluginInfo::GetInstance()
43 {
44     static ExtensionPluginInfo instance;
45     return instance;
46 }
47 
Preload()48 void ExtensionPluginInfo::Preload()
49 {
50     // scan all extensions in path
51     std::vector<std::string> extensionFiles;
52     ScanExtensions(extensionFiles);
53     ParseExtensions(extensionFiles);
54 }
55 
GetExtensionPlugins()56 std::vector<ExtensionPluginItem> ExtensionPluginInfo::GetExtensionPlugins()
57 {
58     return extensionPlugins_;
59 }
60 
ParseExtensions(const std::vector<std::string> & extensionFiles)61 void ExtensionPluginInfo::ParseExtensions(const std::vector<std::string>& extensionFiles)
62 {
63     if (extensionFiles.empty()) {
64         HILOG_ERROR("no extension files.");
65         return;
66     }
67 
68     for (auto& file : extensionFiles) {
69         HILOG_DEBUG("Begin load extension file:%{public}s", file.c_str());
70         std::map<std::string, std::string> params =
71             AbilityRuntime::ExtensionModuleLoader::GetLoader(file.c_str()).GetParams();
72         if (params.empty()) {
73             HILOG_ERROR("no extension params.");
74             continue;
75         }
76         // get extension name and type
77         std::map<std::string, std::string>::iterator it = params.find(EXTENSION_PARAMS_TYPE);
78         if (it == params.end()) {
79             HILOG_ERROR("no extension type.");
80             continue;
81         }
82         int32_t type = -1;
83         try {
84             type = static_cast<int32_t>(std::stoi(it->second));
85         } catch (...) {
86             HILOG_WARN("stoi(%{public}s) failed", it->second.c_str());
87             continue;
88         }
89 
90         it = params.find(EXTENSION_PARAMS_NAME);
91         if (it == params.end()) {
92             HILOG_ERROR("no extension name.");
93             continue;
94         }
95         std::string extensionName = it->second;
96 
97         ExtensionPluginItem item;
98         item.extensionType = type;
99         item.extensionName = extensionName;
100         item.extensionLibFile = file;
101         extensionPlugins_.emplace_back(item);
102         HILOG_DEBUG("Success load extension type: %{public}d, name:%{public}s", type, extensionName.c_str());
103     }
104 }
105 
ScanExtensions(std::vector<std::string> & files)106 bool ExtensionPluginInfo::ScanExtensions(std::vector<std::string>& files)
107 {
108     std::string dirPath = EXTENSION_LIB;
109     DIR *dirp = opendir(dirPath.c_str());
110     if (dirp == nullptr) {
111         HILOG_ERROR("ExtensionPluginInfo::ScanDir open dir:%{public}s fail", dirPath.c_str());
112         return false;
113     }
114 
115     struct dirent *dirf = nullptr;
116     for (;;) {
117         dirf = readdir(dirp);
118         if (dirf == nullptr) {
119             break;
120         }
121 
122         std::string currentName(dirf->d_name);
123         if (currentName.compare(".") == 0 || currentName.compare("..") == 0) {
124             continue;
125         }
126 
127         if (CheckFileType(currentName, LIB_TYPE)) {
128             files.emplace_back(dirPath + PATH_SEPARATOR + currentName);
129         }
130     }
131 
132     if (closedir(dirp) == -1) {
133         HILOG_WARN("close dir fail");
134     }
135     return true;
136 }
137 
CheckFileType(const std::string & fileName,const std::string & extensionName)138 bool ExtensionPluginInfo::CheckFileType(const std::string& fileName, const std::string& extensionName)
139 {
140     HILOG_DEBUG("ExtensionPluginInfo::CheckFileType path is %{public}s, support suffix is %{public}s",
141         fileName.c_str(),
142         extensionName.c_str());
143 
144     if (fileName.empty()) {
145         HILOG_ERROR("the file name is empty.");
146         return false;
147     }
148 
149     auto position = fileName.rfind('.');
150     if (position == std::string::npos) {
151         HILOG_WARN("filename no extension name.");
152         return false;
153     }
154 
155     std::string suffixStr = fileName.substr(position);
156     return LowerStr(suffixStr) == extensionName;
157 }
158 }
159 }
160