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