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