• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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