1 /*
2 * Copyright (c) 2021-2022 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 "pre_bundle_profile.h"
17
18 #include "app_log_wrapper.h"
19 #include "string_ex.h"
20
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 const int32_t COMMON_PRIORITY = 0;
25 const int32_t HIGH_PRIORITY = 1;
26 const std::string INSTALL_LIST = "install_list";
27 const std::string UNINSTALL_LIST = "uninstall_list";
28 const std::string RECOVER_LIST = "recover_list";
29 const std::string INSTALL_ABILITY_CONFIGS = "install_ability_configs";
30 const std::string APP_DIR = "app_dir";
31 const std::string REMOVABLE = "removable";
32 const std::string PRIORITY = "priority";
33 const std::string BUNDLE_NAME = "bundleName";
34 const std::string KEEP_ALIVE = "keepAlive";
35 const std::string SINGLETON = "singleton";
36 const std::string ALLOW_COMMON_EVENT = "allowCommonEvent";
37 const std::string RUNNING_RESOURCES_APPLY = "runningResourcesApply";
38 const std::string APP_SIGNATURE = "app_signature";
39 const std::string ASSOCIATED_WAKE_UP = "associatedWakeUp";
40 const std::string RESOURCES_PATH_1 = "/app/ohos.global.systemres";
41 const std::string RESOURCES_PATH_2 = "/app/SystemResources";
42 const std::string ALLOW_APP_DATA_NOT_CLEARED = "allowAppDataNotCleared";
43 const std::string ALLOW_APP_MULTI_PROCESS = "allowAppMultiProcess";
44 const std::string ALLOW_APP_DESKTOP_ICON_HIDE = "allowAppDesktopIconHide";
45 const std::string ALLOW_ABILITY_PRIORITY_QUERIED = "allowAbilityPriorityQueried";
46 const std::string ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS = "allowAbilityExcludeFromMissions";
47 const std::string ALLOW_APP_USE_PRIVILEGE_EXTENSION = "allowAppUsePrivilegeExtension";
48 const std::string ALLOW_FORM_VISIBLE_NOTIFY = "allowFormVisibleNotify";
49 }
50
TransformTo(const nlohmann::json & jsonBuf,std::set<PreScanInfo> & scanInfos) const51 ErrCode PreBundleProfile::TransformTo(
52 const nlohmann::json &jsonBuf,
53 std::set<PreScanInfo> &scanInfos) const
54 {
55 APP_LOGI("transform jsonBuf to PreScanInfos");
56 if (jsonBuf.is_discarded()) {
57 APP_LOGE("profile format error");
58 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
59 }
60
61 if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) {
62 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
63 }
64
65 auto arrays = jsonBuf.at(INSTALL_LIST);
66 if (!arrays.is_array() || arrays.empty()) {
67 APP_LOGE("value is not array");
68 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
69 }
70
71 PreScanInfo preScanInfo;
72 for (const auto &array : arrays) {
73 if (!array.is_object()) {
74 APP_LOGE("array is not json object");
75 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
76 }
77
78 preScanInfo.Reset();
79 const auto &jsonObjectEnd = array.end();
80 int32_t parseResult = ERR_OK;
81 GetValueIfFindKey<std::string>(array,
82 jsonObjectEnd,
83 APP_DIR,
84 preScanInfo.bundleDir,
85 JsonType::STRING,
86 true,
87 parseResult,
88 ArrayType::NOT_ARRAY);
89 GetValueIfFindKey<bool>(array,
90 jsonObjectEnd,
91 REMOVABLE,
92 preScanInfo.removable,
93 JsonType::BOOLEAN,
94 false,
95 parseResult,
96 ArrayType::NOT_ARRAY);
97 bool isResourcesPath =
98 (preScanInfo.bundleDir.find(RESOURCES_PATH_1) != preScanInfo.bundleDir.npos) ||
99 (preScanInfo.bundleDir.find(RESOURCES_PATH_2) != preScanInfo.bundleDir.npos);
100 preScanInfo.priority = isResourcesPath ? HIGH_PRIORITY : COMMON_PRIORITY;
101 if (parseResult == ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP) {
102 APP_LOGE("bundleDir must exist, and it is empty here");
103 continue;
104 }
105
106 if (parseResult != ERR_OK) {
107 APP_LOGE("parse from json failed");
108 return parseResult;
109 }
110
111 APP_LOGD("preScanInfo(%{public}s)", preScanInfo.ToString().c_str());
112 auto iter = std::find(scanInfos.begin(), scanInfos.end(), preScanInfo);
113 if (iter != scanInfos.end()) {
114 APP_LOGD("Replace old preScanInfo(%{public}s)", preScanInfo.bundleDir.c_str());
115 scanInfos.erase(iter);
116 }
117
118 scanInfos.insert(preScanInfo);
119 }
120
121 return ERR_OK;
122 }
123
TransformTo(const nlohmann::json & jsonBuf,std::set<std::string> & uninstallList) const124 ErrCode PreBundleProfile::TransformTo(
125 const nlohmann::json &jsonBuf,
126 std::set<std::string> &uninstallList) const
127 {
128 APP_LOGD("transform jsonBuf to bundleNames");
129 if (jsonBuf.is_discarded()) {
130 APP_LOGE("profile format error");
131 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
132 }
133
134 const auto &jsonObjectEnd = jsonBuf.end();
135 int32_t parseResult = ERR_OK;
136 std::vector<std::string> names;
137 GetValueIfFindKey<std::vector<std::string>>(jsonBuf,
138 jsonObjectEnd,
139 UNINSTALL_LIST,
140 names,
141 JsonType::ARRAY,
142 false,
143 parseResult,
144 ArrayType::STRING);
145 for (const auto &name : names) {
146 APP_LOGD("uninstall bundleName %{public}s", name.c_str());
147 uninstallList.insert(name);
148 }
149
150 names.clear();
151 GetValueIfFindKey<std::vector<std::string>>(jsonBuf,
152 jsonObjectEnd,
153 RECOVER_LIST,
154 names,
155 JsonType::ARRAY,
156 false,
157 parseResult,
158 ArrayType::STRING);
159 for (const auto &name : names) {
160 APP_LOGD("recover bundleName %{public}s", name.c_str());
161 uninstallList.erase(name);
162 }
163
164 return parseResult;
165 }
166
TransformTo(const nlohmann::json & jsonBuf,std::set<PreBundleConfigInfo> & preBundleConfigInfos) const167 ErrCode PreBundleProfile::TransformTo(
168 const nlohmann::json &jsonBuf,
169 std::set<PreBundleConfigInfo> &preBundleConfigInfos) const
170 {
171 APP_LOGI("transform jsonBuf to preBundleConfigInfos");
172 if (jsonBuf.is_discarded()) {
173 APP_LOGE("profile format error");
174 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
175 }
176
177 if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) {
178 APP_LOGE("installList no exist");
179 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
180 }
181
182 auto arrays = jsonBuf.at(INSTALL_LIST);
183 if (!arrays.is_array() || arrays.empty()) {
184 APP_LOGE("value is not array");
185 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
186 }
187
188 PreBundleConfigInfo preBundleConfigInfo;
189 for (const auto &array : arrays) {
190 if (!array.is_object()) {
191 APP_LOGE("array is not json object");
192 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
193 }
194
195 preBundleConfigInfo.Reset();
196 const auto &jsonObjectEnd = array.end();
197 int32_t parseResult = ERR_OK;
198 GetValueIfFindKey<std::string>(array,
199 jsonObjectEnd,
200 BUNDLE_NAME,
201 preBundleConfigInfo.bundleName,
202 JsonType::STRING,
203 true,
204 parseResult,
205 ArrayType::NOT_ARRAY);
206 GetValueIfFindKey<bool>(array,
207 jsonObjectEnd,
208 KEEP_ALIVE,
209 preBundleConfigInfo.keepAlive,
210 JsonType::BOOLEAN,
211 false,
212 parseResult,
213 ArrayType::NOT_ARRAY);
214 GetValueIfFindKey<bool>(array,
215 jsonObjectEnd,
216 SINGLETON,
217 preBundleConfigInfo.singleton,
218 JsonType::BOOLEAN,
219 false,
220 parseResult,
221 ArrayType::NOT_ARRAY);
222 GetValueIfFindKey<std::vector<std::string>>(array,
223 jsonObjectEnd,
224 ALLOW_COMMON_EVENT,
225 preBundleConfigInfo.allowCommonEvent,
226 JsonType::ARRAY,
227 false,
228 parseResult,
229 ArrayType::STRING);
230 GetValueIfFindKey<std::vector<std::string>>(array,
231 jsonObjectEnd,
232 APP_SIGNATURE,
233 preBundleConfigInfo.appSignature,
234 JsonType::ARRAY,
235 false,
236 parseResult,
237 ArrayType::STRING);
238 GetValueIfFindKey<bool>(array,
239 jsonObjectEnd,
240 RUNNING_RESOURCES_APPLY,
241 preBundleConfigInfo.runningResourcesApply,
242 JsonType::BOOLEAN,
243 false,
244 parseResult,
245 ArrayType::NOT_ARRAY);
246 GetValueIfFindKey<bool>(array,
247 jsonObjectEnd,
248 ASSOCIATED_WAKE_UP,
249 preBundleConfigInfo.associatedWakeUp,
250 JsonType::BOOLEAN,
251 false,
252 parseResult,
253 ArrayType::NOT_ARRAY);
254 GetValueIfFindKey<bool>(array,
255 jsonObjectEnd,
256 ALLOW_APP_DATA_NOT_CLEARED,
257 preBundleConfigInfo.userDataClearable,
258 JsonType::BOOLEAN,
259 false,
260 parseResult,
261 ArrayType::NOT_ARRAY);
262 GetValueIfFindKey<bool>(array,
263 jsonObjectEnd,
264 ALLOW_APP_MULTI_PROCESS,
265 preBundleConfigInfo.allowMultiProcess,
266 JsonType::BOOLEAN,
267 false,
268 parseResult,
269 ArrayType::NOT_ARRAY);
270 GetValueIfFindKey<bool>(array,
271 jsonObjectEnd,
272 ALLOW_APP_DESKTOP_ICON_HIDE,
273 preBundleConfigInfo.hideDesktopIcon,
274 JsonType::BOOLEAN,
275 false,
276 parseResult,
277 ArrayType::NOT_ARRAY);
278 GetValueIfFindKey<bool>(array,
279 jsonObjectEnd,
280 ALLOW_ABILITY_PRIORITY_QUERIED,
281 preBundleConfigInfo.allowQueryPriority,
282 JsonType::BOOLEAN,
283 false,
284 parseResult,
285 ArrayType::NOT_ARRAY);
286 GetValueIfFindKey<bool>(array,
287 jsonObjectEnd,
288 ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS,
289 preBundleConfigInfo.allowExcludeFromMissions,
290 JsonType::BOOLEAN,
291 false,
292 parseResult,
293 ArrayType::NOT_ARRAY);
294 GetValueIfFindKey<bool>(array,
295 jsonObjectEnd,
296 ALLOW_APP_USE_PRIVILEGE_EXTENSION,
297 preBundleConfigInfo.allowUsePrivilegeExtension,
298 JsonType::BOOLEAN,
299 false,
300 parseResult,
301 ArrayType::NOT_ARRAY);
302 GetValueIfFindKey<bool>(array,
303 jsonObjectEnd,
304 ALLOW_FORM_VISIBLE_NOTIFY,
305 preBundleConfigInfo.formVisibleNotify,
306 JsonType::BOOLEAN,
307 false,
308 parseResult,
309 ArrayType::NOT_ARRAY);
310 if (array.find(ALLOW_APP_DATA_NOT_CLEARED) != jsonObjectEnd) {
311 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_DATA_NOT_CLEARED);
312 preBundleConfigInfo.userDataClearable = !preBundleConfigInfo.userDataClearable;
313 }
314 if (array.find(ALLOW_APP_MULTI_PROCESS) != jsonObjectEnd) {
315 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_MULTI_PROCESS);
316 }
317 if (array.find(ALLOW_APP_DESKTOP_ICON_HIDE) != jsonObjectEnd) {
318 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_DESKTOP_ICON_HIDE);
319 }
320 if (array.find(ALLOW_ABILITY_PRIORITY_QUERIED) != jsonObjectEnd) {
321 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_ABILITY_PRIORITY_QUERIED);
322 }
323 if (array.find(ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS) != jsonObjectEnd) {
324 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS);
325 }
326 if (array.find(ALLOW_APP_USE_PRIVILEGE_EXTENSION) != jsonObjectEnd) {
327 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_USE_PRIVILEGE_EXTENSION);
328 }
329 if (array.find(ALLOW_FORM_VISIBLE_NOTIFY) != jsonObjectEnd) {
330 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_FORM_VISIBLE_NOTIFY);
331 }
332 if (parseResult == ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP) {
333 APP_LOGE("bundlename must exist, and it is empty here");
334 continue;
335 }
336
337 if (parseResult != ERR_OK) {
338 APP_LOGE("parse from json failed");
339 return parseResult;
340 }
341
342 APP_LOGD("preBundleConfigInfo(%{public}s)", preBundleConfigInfo.ToString().c_str());
343 auto iter = preBundleConfigInfos.find(preBundleConfigInfo);
344 if (iter != preBundleConfigInfos.end()) {
345 APP_LOGD("Replace old preBundleConfigInfo(%{public}s)",
346 preBundleConfigInfo.bundleName.c_str());
347 preBundleConfigInfos.erase(iter);
348 }
349
350 preBundleConfigInfos.insert(preBundleConfigInfo);
351 }
352
353 return ERR_OK;
354 }
355 } // namespace AppExecFwk
356 } // namespace OHOS
357