1 /*
2 * Copyright (c) 2024 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 "parser_util.h"
17
18 #include <fstream>
19 #include <unistd.h>
20
21 #include "config_policy_utils.h"
22 #include "hilog_tag_wrapper.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 namespace {
27 constexpr const char *DEFAULT_PRE_BUNDLE_ROOT_DIR = "/system";
28 constexpr const char *PRODUCT_SUFFIX = "/etc/app";
29 constexpr const char *INSTALL_LIST_CAPABILITY_CONFIG = "/install_list_capability.json";
30 constexpr const char *INSTALL_LIST = "install_list";
31 constexpr const char *BUNDLE_NAME = "bundleName";
32 constexpr const char *KEEP_ALIVE = "keepAlive";
33 constexpr const char *KEEP_ALIVE_ENABLE = "keepAliveEnable";
34 constexpr const char *KEEP_ALIVE_CONFIGURED_LIST = "keepAliveConfiguredList";
35
36 } // namespace
GetInstance()37 ParserUtil &ParserUtil::GetInstance()
38 {
39 static ParserUtil instance;
40 return instance;
41 }
42
GetResidentProcessRawData(std::vector<std::tuple<std::string,std::string,std::string>> & list)43 void ParserUtil::GetResidentProcessRawData(std::vector<std::tuple<std::string, std::string, std::string>> &list)
44 {
45 std::vector<std::string> rootDirList;
46 GetPreInstallRootDirList(rootDirList);
47
48 for (auto &root : rootDirList) {
49 auto fileDir = root.append(PRODUCT_SUFFIX).append(INSTALL_LIST_CAPABILITY_CONFIG);
50 TAG_LOGD(AAFwkTag::ABILITYMGR, "Search file dir : %{public}s", fileDir.c_str());
51 ParsePreInstallAbilityConfig(fileDir, list);
52 }
53 }
54
ParsePreInstallAbilityConfig(const std::string & filePath,std::vector<std::tuple<std::string,std::string,std::string>> & list)55 void ParserUtil::ParsePreInstallAbilityConfig(
56 const std::string &filePath, std::vector<std::tuple<std::string, std::string, std::string>> &list)
57 {
58 nlohmann::json jsonBuf;
59 if (!ReadFileIntoJson(filePath, jsonBuf)) {
60 return;
61 }
62
63 if (jsonBuf.is_discarded()) {
64 return;
65 }
66
67 FilterInfoFromJson(jsonBuf, list);
68 }
69
FilterInfoFromJson(nlohmann::json & jsonBuf,std::vector<std::tuple<std::string,std::string,std::string>> & list)70 bool ParserUtil::FilterInfoFromJson(
71 nlohmann::json &jsonBuf, std::vector<std::tuple<std::string, std::string, std::string>> &list)
72 {
73 if (jsonBuf.is_discarded()) {
74 TAG_LOGE(AAFwkTag::ABILITYMGR, "Profile format error");
75 return false;
76 }
77
78 if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) {
79 TAG_LOGE(AAFwkTag::ABILITYMGR, "InstallList not exist");
80 return false;
81 }
82
83 auto arrays = jsonBuf.at(INSTALL_LIST);
84 if (!arrays.is_array() || arrays.empty()) {
85 TAG_LOGE(AAFwkTag::ABILITYMGR, "Array not found");
86 return false;
87 }
88
89 std::string bundleName;
90 std::string KeepAliveEnable = "1";
91 std::string KeepAliveConfiguredList;
92 for (const auto &array : arrays) {
93 if (!array.is_object()) {
94 continue;
95 }
96
97 // Judgment logic exists, not found, not bool, not resident process
98 if (!(array.find(KEEP_ALIVE) != array.end() && array.at(KEEP_ALIVE).is_boolean() &&
99 array.at(KEEP_ALIVE).get<bool>())) {
100 continue;
101 }
102
103 if (!(array.find(BUNDLE_NAME) != array.end() && array.at(BUNDLE_NAME).is_string())) {
104 continue;
105 }
106
107 bundleName = array.at(BUNDLE_NAME).get<std::string>();
108
109 if (array.find(KEEP_ALIVE_ENABLE) != array.end() && array.at(KEEP_ALIVE_ENABLE).is_boolean()) {
110 auto val = array.at(KEEP_ALIVE_ENABLE).get<bool>();
111 KeepAliveEnable = std::to_string(val);
112 }
113
114 if (array.find(KEEP_ALIVE_CONFIGURED_LIST) != array.end() && array.at(KEEP_ALIVE_CONFIGURED_LIST).is_array()) {
115 // Save directly in the form of an array and parse it when in use
116 KeepAliveConfiguredList = array.at(KEEP_ALIVE_CONFIGURED_LIST).dump();
117 }
118
119 list.emplace_back(std::make_tuple(bundleName, KeepAliveEnable, KeepAliveConfiguredList));
120 bundleName.clear();
121 KeepAliveEnable = "1";
122 KeepAliveConfiguredList.clear();
123 }
124
125 return true;
126 }
127
GetPreInstallRootDirList(std::vector<std::string> & rootDirList)128 void ParserUtil::GetPreInstallRootDirList(std::vector<std::string> &rootDirList)
129 {
130 auto cfgDirList = GetCfgDirList();
131 if (cfgDirList != nullptr) {
132 for (const auto &cfgDir : cfgDirList->paths) {
133 if (cfgDir == nullptr) {
134 continue;
135 }
136 rootDirList.emplace_back(cfgDir);
137 }
138
139 FreeCfgDirList(cfgDirList);
140 }
141 bool ret = std::find(rootDirList.begin(), rootDirList.end(), DEFAULT_PRE_BUNDLE_ROOT_DIR) != rootDirList.end();
142 if (!ret) {
143 rootDirList.emplace_back(DEFAULT_PRE_BUNDLE_ROOT_DIR);
144 }
145 }
146
ReadFileIntoJson(const std::string & filePath,nlohmann::json & jsonBuf)147 bool ParserUtil::ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf)
148 {
149 if (access(filePath.c_str(), F_OK) != 0) {
150 TAG_LOGE(AAFwkTag::ABILITYMGR, "File path is not exist.");
151 return false;
152 }
153
154 if (filePath.empty()) {
155 TAG_LOGE(AAFwkTag::ABILITYMGR, "File path empty.");
156 return false;
157 }
158
159 char path[PATH_MAX] = {0};
160 if (realpath(filePath.c_str(), path) == nullptr) {
161 TAG_LOGE(AAFwkTag::ABILITYMGR, "realpath error, errno is %{public}d.", errno);
162 return false;
163 }
164
165 std::ifstream fin(path);
166 if (!fin.is_open()) {
167 TAG_LOGE(AAFwkTag::ABILITYMGR, "File path exception.");
168 return false;
169 }
170
171 fin.seekg(0, std::ios::end);
172 int64_t size = fin.tellg();
173 if (size <= 0) {
174 TAG_LOGE(AAFwkTag::ABILITYMGR, "The file is an empty file!");
175 fin.close();
176 return false;
177 }
178
179 fin.seekg(0, std::ios::beg);
180 jsonBuf = nlohmann::json::parse(fin, nullptr, false);
181 fin.close();
182 if (jsonBuf.is_discarded()) {
183 TAG_LOGE(AAFwkTag::ABILITYMGR, "Bad profile file");
184 return false;
185 }
186 return true;
187 }
188 } // namespace AbilityRuntime
189 } // namespace OHOS