1 /*
2 * Copyright (c) 2021-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 "pre_bundle_profile.h"
17
18 namespace OHOS {
19 namespace AppExecFwk {
20 namespace {
21 const int32_t COMMON_PRIORITY = 0;
22 const int32_t HIGH_PRIORITY = 1;
23 const std::string INSTALL_LIST = "install_list";
24 const std::string UNINSTALL_LIST = "uninstall_list";
25 const std::string EXTENSION_TYPE = "extensionType";
26 const std::string RECOVER_LIST = "recover_list";
27 const std::string INSTALL_ABILITY_CONFIGS = "install_ability_configs";
28 const std::string APP_DIR = "app_dir";
29 const std::string REMOVABLE = "removable";
30 const std::string PRIORITY = "priority";
31 const std::string BUNDLE_NAME = "bundleName";
32 const std::string TYPE_NAME = "name";
33 const std::string KEEP_ALIVE = "keepAlive";
34 const std::string SINGLETON = "singleton";
35 const std::string ALLOW_COMMON_EVENT = "allowCommonEvent";
36 const std::string RUNNING_RESOURCES_APPLY = "runningResourcesApply";
37 const std::string APP_SIGNATURE = "app_signature";
38 const std::string ASSOCIATED_WAKE_UP = "associatedWakeUp";
39 const std::string RESOURCES_PATH_1 = "/app/ohos.global.systemres";
40 const std::string RESOURCES_PATH_2 = "/app/SystemResources";
41 const std::string ALLOW_APP_DATA_NOT_CLEARED = "allowAppDataNotCleared";
42 const std::string ALLOW_APP_MULTI_PROCESS = "allowAppMultiProcess";
43 const std::string ALLOW_APP_DESKTOP_ICON_HIDE = "allowAppDesktopIconHide";
44 const std::string ALLOW_ABILITY_PRIORITY_QUERIED = "allowAbilityPriorityQueried";
45 const std::string ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS = "allowAbilityExcludeFromMissions";
46 const std::string ALLOW_MISSION_NOT_CLEARED = "allowMissionNotCleared";
47 const std::string ALLOW_APP_USE_PRIVILEGE_EXTENSION = "allowAppUsePrivilegeExtension";
48 const std::string ALLOW_FORM_VISIBLE_NOTIFY = "allowFormVisibleNotify";
49 const std::string ALLOW_APP_SHARE_LIBRARY = "allowAppShareLibrary";
50 const std::string ALLOW_ENABLE_NOTIFICATION = "allowEnableNotification";
51 const std::string ALLOW_APP_RUN_WHEN_DEVICE_FIRST_LOCKED = "allowAppRunWhenDeviceFirstLocked";
52 const std::string RESOURCES_APPLY = "resourcesApply";
53 }
54
TransformTo(const nlohmann::json & jsonBuf,std::set<PreScanInfo> & scanInfos) const55 ErrCode PreBundleProfile::TransformTo(
56 const nlohmann::json &jsonBuf,
57 std::set<PreScanInfo> &scanInfos) const
58 {
59 APP_LOGI("transform jsonBuf to PreScanInfos");
60 if (jsonBuf.is_discarded()) {
61 APP_LOGE("profile format error");
62 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
63 }
64
65 if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) {
66 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
67 }
68
69 auto arrays = jsonBuf.at(INSTALL_LIST);
70 if (!arrays.is_array() || arrays.empty()) {
71 APP_LOGE("value is not array");
72 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
73 }
74
75 PreScanInfo preScanInfo;
76 for (const auto &array : arrays) {
77 if (!array.is_object()) {
78 APP_LOGE("array is not json object");
79 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
80 }
81
82 preScanInfo.Reset();
83 const auto &jsonObjectEnd = array.end();
84 int32_t parseResult = ERR_OK;
85 GetValueIfFindKey<std::string>(array,
86 jsonObjectEnd,
87 APP_DIR,
88 preScanInfo.bundleDir,
89 JsonType::STRING,
90 true,
91 parseResult,
92 ArrayType::NOT_ARRAY);
93 GetValueIfFindKey<bool>(array,
94 jsonObjectEnd,
95 REMOVABLE,
96 preScanInfo.removable,
97 JsonType::BOOLEAN,
98 false,
99 parseResult,
100 ArrayType::NOT_ARRAY);
101 bool isResourcesPath =
102 (preScanInfo.bundleDir.find(RESOURCES_PATH_1) != preScanInfo.bundleDir.npos) ||
103 (preScanInfo.bundleDir.find(RESOURCES_PATH_2) != preScanInfo.bundleDir.npos);
104 preScanInfo.priority = isResourcesPath ? HIGH_PRIORITY : COMMON_PRIORITY;
105 if (parseResult == ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP) {
106 APP_LOGE("bundleDir must exist, and it is empty here");
107 continue;
108 }
109
110 if (parseResult != ERR_OK) {
111 APP_LOGE("parse from json failed");
112 return parseResult;
113 }
114
115 APP_LOGD("preScanInfo(%{public}s)", preScanInfo.ToString().c_str());
116 auto iter = std::find(scanInfos.begin(), scanInfos.end(), preScanInfo);
117 if (iter != scanInfos.end()) {
118 APP_LOGD("Replace old preScanInfo(%{public}s)", preScanInfo.bundleDir.c_str());
119 scanInfos.erase(iter);
120 }
121
122 scanInfos.insert(preScanInfo);
123 }
124
125 return ERR_OK;
126 }
127
TransformTo(const nlohmann::json & jsonBuf,std::set<std::string> & uninstallList) const128 ErrCode PreBundleProfile::TransformTo(
129 const nlohmann::json &jsonBuf,
130 std::set<std::string> &uninstallList) const
131 {
132 APP_LOGD("transform jsonBuf to bundleNames");
133 if (jsonBuf.is_discarded()) {
134 APP_LOGE("profile format error");
135 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
136 }
137
138 const auto &jsonObjectEnd = jsonBuf.end();
139 int32_t parseResult = ERR_OK;
140 std::vector<std::string> names;
141 GetValueIfFindKey<std::vector<std::string>>(jsonBuf,
142 jsonObjectEnd,
143 UNINSTALL_LIST,
144 names,
145 JsonType::ARRAY,
146 false,
147 parseResult,
148 ArrayType::STRING);
149 for (const auto &name : names) {
150 APP_LOGD("uninstall bundleName %{public}s", name.c_str());
151 uninstallList.insert(name);
152 }
153
154 names.clear();
155 GetValueIfFindKey<std::vector<std::string>>(jsonBuf,
156 jsonObjectEnd,
157 RECOVER_LIST,
158 names,
159 JsonType::ARRAY,
160 false,
161 parseResult,
162 ArrayType::STRING);
163 for (const auto &name : names) {
164 APP_LOGD("recover bundleName %{public}s", name.c_str());
165 uninstallList.erase(name);
166 }
167
168 return parseResult;
169 }
170
TransformTo(const nlohmann::json & jsonBuf,std::set<PreBundleConfigInfo> & preBundleConfigInfos) const171 ErrCode PreBundleProfile::TransformTo(
172 const nlohmann::json &jsonBuf,
173 std::set<PreBundleConfigInfo> &preBundleConfigInfos) const
174 {
175 APP_LOGI("transform jsonBuf to preBundleConfigInfos");
176 if (jsonBuf.is_discarded()) {
177 APP_LOGE("profile format error");
178 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
179 }
180
181 if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) {
182 APP_LOGE("installList no exist");
183 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
184 }
185
186 auto arrays = jsonBuf.at(INSTALL_LIST);
187 if (!arrays.is_array() || arrays.empty()) {
188 APP_LOGE("value is not array");
189 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
190 }
191
192 PreBundleConfigInfo preBundleConfigInfo;
193 for (const auto &array : arrays) {
194 if (!array.is_object()) {
195 APP_LOGE("array is not json object");
196 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
197 }
198
199 preBundleConfigInfo.Reset();
200 const auto &jsonObjectEnd = array.end();
201 int32_t parseResult = ERR_OK;
202 GetValueIfFindKey<std::string>(array,
203 jsonObjectEnd,
204 BUNDLE_NAME,
205 preBundleConfigInfo.bundleName,
206 JsonType::STRING,
207 true,
208 parseResult,
209 ArrayType::NOT_ARRAY);
210 GetValueIfFindKey<bool>(array,
211 jsonObjectEnd,
212 KEEP_ALIVE,
213 preBundleConfigInfo.keepAlive,
214 JsonType::BOOLEAN,
215 false,
216 parseResult,
217 ArrayType::NOT_ARRAY);
218 GetValueIfFindKey<bool>(array,
219 jsonObjectEnd,
220 SINGLETON,
221 preBundleConfigInfo.singleton,
222 JsonType::BOOLEAN,
223 false,
224 parseResult,
225 ArrayType::NOT_ARRAY);
226 GetValueIfFindKey<std::vector<std::string>>(array,
227 jsonObjectEnd,
228 ALLOW_COMMON_EVENT,
229 preBundleConfigInfo.allowCommonEvent,
230 JsonType::ARRAY,
231 false,
232 parseResult,
233 ArrayType::STRING);
234 GetValueIfFindKey<std::vector<std::string>>(array,
235 jsonObjectEnd,
236 APP_SIGNATURE,
237 preBundleConfigInfo.appSignature,
238 JsonType::ARRAY,
239 false,
240 parseResult,
241 ArrayType::STRING);
242 GetValueIfFindKey<bool>(array,
243 jsonObjectEnd,
244 RUNNING_RESOURCES_APPLY,
245 preBundleConfigInfo.runningResourcesApply,
246 JsonType::BOOLEAN,
247 false,
248 parseResult,
249 ArrayType::NOT_ARRAY);
250 GetValueIfFindKey<bool>(array,
251 jsonObjectEnd,
252 ASSOCIATED_WAKE_UP,
253 preBundleConfigInfo.associatedWakeUp,
254 JsonType::BOOLEAN,
255 false,
256 parseResult,
257 ArrayType::NOT_ARRAY);
258 GetValueIfFindKey<bool>(array,
259 jsonObjectEnd,
260 ALLOW_APP_DATA_NOT_CLEARED,
261 preBundleConfigInfo.userDataClearable,
262 JsonType::BOOLEAN,
263 false,
264 parseResult,
265 ArrayType::NOT_ARRAY);
266 GetValueIfFindKey<bool>(array,
267 jsonObjectEnd,
268 ALLOW_APP_MULTI_PROCESS,
269 preBundleConfigInfo.allowMultiProcess,
270 JsonType::BOOLEAN,
271 false,
272 parseResult,
273 ArrayType::NOT_ARRAY);
274 GetValueIfFindKey<bool>(array,
275 jsonObjectEnd,
276 ALLOW_APP_DESKTOP_ICON_HIDE,
277 preBundleConfigInfo.hideDesktopIcon,
278 JsonType::BOOLEAN,
279 false,
280 parseResult,
281 ArrayType::NOT_ARRAY);
282 GetValueIfFindKey<bool>(array,
283 jsonObjectEnd,
284 ALLOW_ABILITY_PRIORITY_QUERIED,
285 preBundleConfigInfo.allowQueryPriority,
286 JsonType::BOOLEAN,
287 false,
288 parseResult,
289 ArrayType::NOT_ARRAY);
290 GetValueIfFindKey<bool>(array,
291 jsonObjectEnd,
292 ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS,
293 preBundleConfigInfo.allowExcludeFromMissions,
294 JsonType::BOOLEAN,
295 false,
296 parseResult,
297 ArrayType::NOT_ARRAY);
298 GetValueIfFindKey<bool>(array,
299 jsonObjectEnd,
300 ALLOW_MISSION_NOT_CLEARED,
301 preBundleConfigInfo.allowMissionNotCleared,
302 JsonType::BOOLEAN,
303 false,
304 parseResult,
305 ArrayType::NOT_ARRAY);
306 GetValueIfFindKey<bool>(array,
307 jsonObjectEnd,
308 ALLOW_APP_USE_PRIVILEGE_EXTENSION,
309 preBundleConfigInfo.allowUsePrivilegeExtension,
310 JsonType::BOOLEAN,
311 false,
312 parseResult,
313 ArrayType::NOT_ARRAY);
314 GetValueIfFindKey<bool>(array,
315 jsonObjectEnd,
316 ALLOW_FORM_VISIBLE_NOTIFY,
317 preBundleConfigInfo.formVisibleNotify,
318 JsonType::BOOLEAN,
319 false,
320 parseResult,
321 ArrayType::NOT_ARRAY);
322 GetValueIfFindKey<bool>(array,
323 jsonObjectEnd,
324 ALLOW_APP_SHARE_LIBRARY,
325 preBundleConfigInfo.appShareLibrary,
326 JsonType::BOOLEAN,
327 false,
328 parseResult,
329 ArrayType::NOT_ARRAY);
330 GetValueIfFindKey<bool>(array,
331 jsonObjectEnd,
332 ALLOW_ENABLE_NOTIFICATION,
333 preBundleConfigInfo.allowEnableNotification,
334 JsonType::BOOLEAN,
335 false,
336 parseResult,
337 ArrayType::NOT_ARRAY);
338 GetValueIfFindKey<bool>(array,
339 jsonObjectEnd,
340 ALLOW_APP_RUN_WHEN_DEVICE_FIRST_LOCKED,
341 preBundleConfigInfo.allowAppRunWhenDeviceFirstLocked,
342 JsonType::BOOLEAN,
343 false,
344 parseResult,
345 ArrayType::NOT_ARRAY);
346 GetValueIfFindKey<std::vector<int32_t>>(array,
347 jsonObjectEnd,
348 RESOURCES_APPLY,
349 preBundleConfigInfo.resourcesApply,
350 JsonType::ARRAY,
351 false,
352 parseResult,
353 ArrayType::NUMBER);
354 if (array.find(ALLOW_APP_DATA_NOT_CLEARED) != jsonObjectEnd) {
355 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_DATA_NOT_CLEARED);
356 preBundleConfigInfo.userDataClearable = !preBundleConfigInfo.userDataClearable;
357 }
358 if (array.find(ALLOW_APP_MULTI_PROCESS) != jsonObjectEnd) {
359 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_MULTI_PROCESS);
360 }
361 if (array.find(ALLOW_APP_DESKTOP_ICON_HIDE) != jsonObjectEnd) {
362 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_DESKTOP_ICON_HIDE);
363 }
364 if (array.find(ALLOW_ABILITY_PRIORITY_QUERIED) != jsonObjectEnd) {
365 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_ABILITY_PRIORITY_QUERIED);
366 }
367 if (array.find(ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS) != jsonObjectEnd) {
368 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS);
369 }
370 if (array.find(ALLOW_MISSION_NOT_CLEARED) != jsonObjectEnd) {
371 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_MISSION_NOT_CLEARED);
372 }
373 if (array.find(ALLOW_APP_USE_PRIVILEGE_EXTENSION) != jsonObjectEnd) {
374 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_USE_PRIVILEGE_EXTENSION);
375 }
376 if (array.find(ALLOW_FORM_VISIBLE_NOTIFY) != jsonObjectEnd) {
377 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_FORM_VISIBLE_NOTIFY);
378 }
379 if (array.find(ALLOW_APP_SHARE_LIBRARY) != jsonObjectEnd) {
380 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_APP_SHARE_LIBRARY);
381 }
382 if (array.find(ALLOW_ENABLE_NOTIFICATION) != jsonObjectEnd) {
383 preBundleConfigInfo.existInJsonFile.push_back(ALLOW_ENABLE_NOTIFICATION);
384 }
385 if (parseResult == ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP) {
386 APP_LOGE("bundlename must exist, and it is empty here");
387 continue;
388 }
389
390 if (parseResult != ERR_OK) {
391 APP_LOGE("parse from json failed");
392 return parseResult;
393 }
394
395 APP_LOGD("preBundleConfigInfo(%{public}s)", preBundleConfigInfo.ToString().c_str());
396 auto iter = preBundleConfigInfos.find(preBundleConfigInfo);
397 if (iter != preBundleConfigInfos.end()) {
398 APP_LOGD("Replace old preBundleConfigInfo(%{public}s)",
399 preBundleConfigInfo.bundleName.c_str());
400 preBundleConfigInfos.erase(iter);
401 }
402
403 preBundleConfigInfos.insert(preBundleConfigInfo);
404 }
405
406 return ERR_OK;
407 }
408
TransformJsonToExtensionTypeList(const nlohmann::json & jsonBuf,std::set<std::string> & extensionTypeList) const409 ErrCode PreBundleProfile::TransformJsonToExtensionTypeList(
410 const nlohmann::json &jsonBuf, std::set<std::string> &extensionTypeList) const
411 {
412 if (jsonBuf.is_discarded()) {
413 APP_LOGE("Profile format error");
414 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
415 }
416
417 if (jsonBuf.find(EXTENSION_TYPE) == jsonBuf.end()) {
418 APP_LOGE("Profile does not have 'extensionType'key");
419 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
420 }
421
422 auto arrays = jsonBuf.at(EXTENSION_TYPE);
423 if (!arrays.is_array() || arrays.empty()) {
424 APP_LOGE("Value is not array");
425 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
426 }
427
428 for (const auto &array : arrays) {
429 if (!array.is_object()) {
430 APP_LOGE("Array is not json object");
431 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
432 }
433
434 std::string extensionAbilityType;
435 const auto &jsonObjectEnd = array.end();
436 int32_t parseResult = ERR_OK;
437 GetValueIfFindKey<std::string>(array,
438 jsonObjectEnd,
439 TYPE_NAME,
440 extensionAbilityType,
441 JsonType::STRING,
442 true,
443 parseResult,
444 ArrayType::NOT_ARRAY);
445 extensionTypeList.insert(extensionAbilityType);
446 }
447
448 return ERR_OK;
449 }
450 } // namespace AppExecFwk
451 } // namespace OHOS
452