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