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