1 /*
2 * Copyright (c) 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 "app_utils.h"
17 #include "json_utils.h"
18 #include "hilog_tag_wrapper.h"
19 #include "nlohmann/json.hpp"
20 #include "parameters.h"
21 #include "scene_board_judgement.h"
22
23 namespace OHOS {
24 namespace AAFwk {
25 namespace {
26 constexpr const char* BUNDLE_NAME_LAUNCHER = "com.ohos.launcher";
27 constexpr const char* BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
28 constexpr const char* LAUNCHER_ABILITY_NAME = "com.ohos.launcher.MainAbility";
29 constexpr const char* SCENEBOARD_ABILITY_NAME = "com.ohos.sceneboard.MainAbility";
30 constexpr const char* INHERIT_WINDOW_SPLIT_SCREEN_MODE = "persist.sys.abilityms.inherit_window_split_screen_mode";
31 constexpr const char* SUPPORT_ANCO_APP = "persist.sys.abilityms.support_anco_app";
32 constexpr const char* TIMEOUT_UNIT_TIME_RATIO = "persist.sys.abilityms.timeout_unit_time_ratio";
33 constexpr const char* SELECTOR_DIALOG_POSSION = "persist.sys.abilityms.selector_dialog_possion";
34 constexpr const char* START_SPECIFIED_PROCESS = "persist.sys.abilityms.start_specified_process";
35 constexpr const char* USE_MULTI_RENDER_PROCESS = "persist.sys.abilityms.use_multi_render_process";
36 constexpr const char* LIMIT_MAXIMUM_OF_RENDER_PROCESS = "persist.sys.abilityms.limit_maximum_of_render_process";
37 constexpr const char* GRANT_PERSIST_URI_PERMISSION = "persist.sys.abilityms.grant_persist_uri_permission";
38 constexpr const char* START_OPTIONS_WITH_ANIMATION = "persist.sys.abilityms.start_options_with_animation";
39 constexpr const char* MULTI_PROCESS_MODEL = "persist.sys.abilityms.multi_process_model";
40 constexpr const char* START_OPTIONS_WITH_PROCESS_OPTION = "persist.sys.abilityms.start_options_with_process_option";
41 constexpr const char* MOVE_UI_ABILITY_TO_BACKGROUND_API_ENABLE =
42 "persist.sys.abilityms.move_ui_ability_to_background_api_enable";
43 constexpr const char* CONFIG_PATH = "/etc/ability_runtime/resident_process_in_extreme_memory.json";
44 constexpr const char* RESIDENT_PROCESS_IN_EXTREME_MEMORY = "residentProcessInExtremeMemory";
45 constexpr const char* BUNDLE_NAME = "bundleName";
46 constexpr const char* ABILITY_NAME = "abilityName";
47 constexpr const char* KEY_IDENTIFIER = "identifier";
48 constexpr const char* ALLOW_NATIVE_CHILD_PROCESS_APPS_CONFIG_PATH =
49 "/etc/ability_runtime/allow_native_child_process_apps.json";
50 constexpr const char* KEY_ALLOW_NATIVE_CHILD_PROCESS_APPS = "allowNativeChildProcessApps";
51 constexpr const char* LAUNCH_EMBEDED_UI_ABILITY = "const.abilityms.launch_embeded_ui_ability";
52 const std::string SUPPROT_NATIVE_CHILD_PROCESS = "persist.sys.abilityms.start_native_child_process";
53 const std::string LIMIT_MAXIMUM_EXTENSIONS_OF_PER_PROCESS =
54 "const.sys.abilityms.limit_maximum_extensions_of_per_process";
55 const std::string LIMIT_MAXIMUM_EXTENSIONS_OF_PER_DEVICE =
56 "const.sys.abilityms.limit_maximum_extensions_of_per_device";
57 const std::string CACHE_EXTENSION_TYPES = "const.sys.abilityms.cache_extension";
58 constexpr const char* START_ABILITY_WITHOUT_CALLERTOKEN = "/system/etc/start_ability_without_caller_token.json";
59 constexpr const char* START_ABILITY_WITHOUT_CALLERTOKEN_PATH =
60 "/etc/ability_runtime/start_ability_without_caller_token.json";
61 constexpr const char* START_ABILITY_WITHOUT_CALLERTOKEN_TITLE = "startAbilityWithoutCallerToken";
62 constexpr const char* MAX_CHILD_PROCESS = "const.max_native_child_process";
63 }
64
~AppUtils()65 AppUtils::~AppUtils() {}
66
AppUtils()67 AppUtils::AppUtils()
68 {
69 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
70 isSceneBoard_ = true;
71 }
72 }
73
GetInstance()74 AppUtils &AppUtils::GetInstance()
75 {
76 static AppUtils utils;
77 return utils;
78 }
79
IsLauncher(const std::string & bundleName) const80 bool AppUtils::IsLauncher(const std::string &bundleName) const
81 {
82 if (isSceneBoard_) {
83 return bundleName == BUNDLE_NAME_SCENEBOARD;
84 }
85
86 return bundleName == BUNDLE_NAME_LAUNCHER;
87 }
88
IsLauncherAbility(const std::string & abilityName) const89 bool AppUtils::IsLauncherAbility(const std::string &abilityName) const
90 {
91 if (isSceneBoard_) {
92 return abilityName == SCENEBOARD_ABILITY_NAME;
93 }
94
95 return abilityName == LAUNCHER_ABILITY_NAME;
96 }
97
IsInheritWindowSplitScreenMode()98 bool AppUtils::IsInheritWindowSplitScreenMode()
99 {
100 if (!isInheritWindowSplitScreenMode_.isLoaded) {
101 isInheritWindowSplitScreenMode_.value = system::GetBoolParameter(INHERIT_WINDOW_SPLIT_SCREEN_MODE, true);
102 isInheritWindowSplitScreenMode_.isLoaded = true;
103 }
104 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isInheritWindowSplitScreenMode_.value);
105 return isInheritWindowSplitScreenMode_.value;
106 }
107
IsSupportAncoApp()108 bool AppUtils::IsSupportAncoApp()
109 {
110 if (!isSupportAncoApp_.isLoaded) {
111 isSupportAncoApp_.value = system::GetBoolParameter(SUPPORT_ANCO_APP, false);
112 isSupportAncoApp_.isLoaded = true;
113 }
114 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isSupportAncoApp_.value);
115 return isSupportAncoApp_.value;
116 }
117
GetTimeoutUnitTimeRatio()118 int32_t AppUtils::GetTimeoutUnitTimeRatio()
119 {
120 if (!timeoutUnitTimeRatio_.isLoaded) {
121 timeoutUnitTimeRatio_.value = system::GetIntParameter<int32_t>(TIMEOUT_UNIT_TIME_RATIO, 1);
122 timeoutUnitTimeRatio_.isLoaded = true;
123 }
124 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", timeoutUnitTimeRatio_.value);
125 return timeoutUnitTimeRatio_.value;
126 }
127
IsSelectorDialogDefaultPossion()128 bool AppUtils::IsSelectorDialogDefaultPossion()
129 {
130 if (!isSelectorDialogDefaultPossion_.isLoaded) {
131 isSelectorDialogDefaultPossion_.value = system::GetBoolParameter(SELECTOR_DIALOG_POSSION, true);
132 isSelectorDialogDefaultPossion_.isLoaded = true;
133 }
134 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isSelectorDialogDefaultPossion_.value);
135 return isSelectorDialogDefaultPossion_.value;
136 }
137
IsStartSpecifiedProcess()138 bool AppUtils::IsStartSpecifiedProcess()
139 {
140 if (!isStartSpecifiedProcess_.isLoaded) {
141 isStartSpecifiedProcess_.value = system::GetBoolParameter(START_SPECIFIED_PROCESS, false);
142 isStartSpecifiedProcess_.isLoaded = true;
143 }
144 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isStartSpecifiedProcess_.value);
145 return isStartSpecifiedProcess_.value;
146 }
147
IsUseMultiRenderProcess()148 bool AppUtils::IsUseMultiRenderProcess()
149 {
150 if (!isUseMultiRenderProcess_.isLoaded) {
151 isUseMultiRenderProcess_.value = system::GetBoolParameter(USE_MULTI_RENDER_PROCESS, true);
152 isUseMultiRenderProcess_.isLoaded = true;
153 }
154 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isUseMultiRenderProcess_.value);
155 return isUseMultiRenderProcess_.value;
156 }
157
IsLimitMaximumOfRenderProcess()158 bool AppUtils::IsLimitMaximumOfRenderProcess()
159 {
160 if (!isLimitMaximumOfRenderProcess_.isLoaded) {
161 isLimitMaximumOfRenderProcess_.value = system::GetBoolParameter(LIMIT_MAXIMUM_OF_RENDER_PROCESS, true);
162 isLimitMaximumOfRenderProcess_.isLoaded = true;
163 }
164 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isLimitMaximumOfRenderProcess_.value);
165 return isLimitMaximumOfRenderProcess_.value;
166 }
167
IsGrantPersistUriPermission()168 bool AppUtils::IsGrantPersistUriPermission()
169 {
170 if (!isGrantPersistUriPermission_.isLoaded) {
171 isGrantPersistUriPermission_.value = system::GetBoolParameter(GRANT_PERSIST_URI_PERMISSION, false);
172 isGrantPersistUriPermission_.isLoaded = true;
173 }
174 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isGrantPersistUriPermission_.value);
175 return isGrantPersistUriPermission_.value;
176 }
177
IsStartOptionsWithAnimation()178 bool AppUtils::IsStartOptionsWithAnimation()
179 {
180 if (!isStartOptionsWithAnimation_.isLoaded) {
181 isStartOptionsWithAnimation_.value = system::GetBoolParameter(START_OPTIONS_WITH_ANIMATION, false);
182 isStartOptionsWithAnimation_.isLoaded = true;
183 }
184 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isStartOptionsWithAnimation_.value);
185 return isStartOptionsWithAnimation_.value;
186 }
187
IsMultiProcessModel()188 bool AppUtils::IsMultiProcessModel()
189 {
190 if (!isMultiProcessModel_.isLoaded) {
191 isMultiProcessModel_.value = system::GetBoolParameter(MULTI_PROCESS_MODEL, false);
192 isMultiProcessModel_.isLoaded = true;
193 }
194 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isMultiProcessModel_.value);
195 return isMultiProcessModel_.value;
196 }
197
IsStartOptionsWithProcessOptions()198 bool AppUtils::IsStartOptionsWithProcessOptions()
199 {
200 if (!isStartOptionsWithProcessOptions_.isLoaded) {
201 isStartOptionsWithProcessOptions_.value = system::GetBoolParameter(START_OPTIONS_WITH_PROCESS_OPTION, false);
202 isStartOptionsWithProcessOptions_.isLoaded = true;
203 }
204 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isStartOptionsWithProcessOptions_.value);
205 return isStartOptionsWithProcessOptions_.value;
206 }
207
EnableMoveUIAbilityToBackgroundApi()208 bool AppUtils::EnableMoveUIAbilityToBackgroundApi()
209 {
210 if (!enableMoveUIAbilityToBackgroundApi_.isLoaded) {
211 enableMoveUIAbilityToBackgroundApi_.value =
212 system::GetBoolParameter(MOVE_UI_ABILITY_TO_BACKGROUND_API_ENABLE, true);
213 enableMoveUIAbilityToBackgroundApi_.isLoaded = true;
214 }
215 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", enableMoveUIAbilityToBackgroundApi_.value);
216 return enableMoveUIAbilityToBackgroundApi_.value;
217 }
218
IsLaunchEmbededUIAbility()219 bool AppUtils::IsLaunchEmbededUIAbility()
220 {
221 if (!isLaunchEmbededUIAbility_.isLoaded) {
222 isLaunchEmbededUIAbility_.value = system::GetBoolParameter(LAUNCH_EMBEDED_UI_ABILITY, false);
223 isLaunchEmbededUIAbility_.isLoaded = true;
224 }
225 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isLaunchEmbededUIAbility_.value);
226 return isLaunchEmbededUIAbility_.value;
227 }
228
IsSupportNativeChildProcess()229 bool AppUtils::IsSupportNativeChildProcess()
230 {
231 if (!isSupportNativeChildProcess_.isLoaded) {
232 isSupportNativeChildProcess_.value = system::GetBoolParameter(SUPPROT_NATIVE_CHILD_PROCESS, false);
233 isSupportNativeChildProcess_.isLoaded = true;
234 }
235 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isSupportNativeChildProcess_.value);
236 return isSupportNativeChildProcess_.value;
237 }
238
IsAllowResidentInExtremeMemory(const std::string & bundleName,const std::string & abilityName)239 bool AppUtils::IsAllowResidentInExtremeMemory(const std::string& bundleName, const std::string& abilityName)
240 {
241 std::lock_guard lock(residentProcessInExtremeMemoryMutex_);
242 if (!residentProcessInExtremeMemory_.isLoaded) {
243 LoadResidentProcessInExtremeMemory();
244 residentProcessInExtremeMemory_.isLoaded = true;
245 }
246 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isSupportNativeChildProcess_.value);
247 for (auto &element : residentProcessInExtremeMemory_.value) {
248 if (bundleName == element.first &&
249 (abilityName == "" || abilityName == element.second)) {
250 return true;
251 }
252 }
253 return false;
254 }
255
LoadResidentProcessInExtremeMemory()256 void AppUtils::LoadResidentProcessInExtremeMemory()
257 {
258 nlohmann::json object;
259 if (!JsonUtils::GetInstance().LoadConfiguration(CONFIG_PATH, object)) {
260 TAG_LOGE(AAFwkTag::ABILITYMGR, "resident process failed");
261 return;
262 }
263 if (!object.contains(RESIDENT_PROCESS_IN_EXTREME_MEMORY)) {
264 TAG_LOGE(AAFwkTag::ABILITYMGR, "resident process invalid");
265 return;
266 }
267
268 for (auto &item : object.at(RESIDENT_PROCESS_IN_EXTREME_MEMORY).items()) {
269 const nlohmann::json& jsonObject = item.value();
270 if (!jsonObject.contains(BUNDLE_NAME) || !jsonObject.at(BUNDLE_NAME).is_string()) {
271 TAG_LOGE(AAFwkTag::ABILITYMGR, "load bundleName failed");
272 return;
273 }
274 if (!jsonObject.contains(ABILITY_NAME) || !jsonObject.at(ABILITY_NAME).is_string()) {
275 TAG_LOGE(AAFwkTag::ABILITYMGR, "load abilityName failed");
276 return;
277 }
278 std::string bundleName = jsonObject.at(BUNDLE_NAME).get<std::string>();
279 std::string abilityName = jsonObject.at(ABILITY_NAME).get<std::string>();
280 residentProcessInExtremeMemory_.value.emplace_back(std::make_pair(bundleName, abilityName));
281 }
282 }
283
IsAllowNativeChildProcess(const std::string & appIdentifier)284 bool AppUtils::IsAllowNativeChildProcess(const std::string &appIdentifier)
285 {
286 TAG_LOGD(AAFwkTag::DEFAULT, "appId:%{private}s", appIdentifier.c_str());
287 if (!allowStartNativeProcessApps_.isLoaded) {
288 LoadAllowNativeChildProcessApps();
289 allowStartNativeProcessApps_.isLoaded = true;
290 }
291 auto &apps = allowStartNativeProcessApps_.value;
292 TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}zu", apps.size());
293 return std::find(apps.begin(), apps.end(), appIdentifier) != apps.end();
294 }
295
LoadAllowNativeChildProcessApps()296 void AppUtils::LoadAllowNativeChildProcessApps()
297 {
298 nlohmann::json object;
299 if (!JsonUtils::GetInstance().LoadConfiguration(ALLOW_NATIVE_CHILD_PROCESS_APPS_CONFIG_PATH, object)) {
300 TAG_LOGE(AAFwkTag::ABILITYMGR, "load child process config failed");
301 return;
302 }
303 if (!object.contains(KEY_ALLOW_NATIVE_CHILD_PROCESS_APPS)) {
304 TAG_LOGE(AAFwkTag::ABILITYMGR, "get key invalid");
305 return;
306 }
307
308 for (auto &item : object.at(KEY_ALLOW_NATIVE_CHILD_PROCESS_APPS).items()) {
309 const nlohmann::json& jsonObject = item.value();
310 if (!jsonObject.contains(KEY_IDENTIFIER) || !jsonObject.at(KEY_IDENTIFIER).is_string()) {
311 TAG_LOGE(AAFwkTag::ABILITYMGR, "load identifier failed");
312 return;
313 }
314 std::string identifier = jsonObject.at(KEY_IDENTIFIER).get<std::string>();
315 allowStartNativeProcessApps_.value.emplace_back(identifier);
316 }
317 }
318
GetLimitMaximumExtensionsPerProc()319 int32_t AppUtils::GetLimitMaximumExtensionsPerProc()
320 {
321 if (!limitMaximumExtensionsPerProc_.isLoaded) {
322 limitMaximumExtensionsPerProc_.value =
323 system::GetIntParameter<int32_t>(LIMIT_MAXIMUM_EXTENSIONS_OF_PER_PROCESS, DEFAULT_MAX_EXT_PER_PROC);
324 limitMaximumExtensionsPerProc_.isLoaded = true;
325 }
326 TAG_LOGD(AAFwkTag::DEFAULT, "limitMaximumExtensionsPerProc: %{public}d", limitMaximumExtensionsPerProc_.value);
327 return limitMaximumExtensionsPerProc_.value;
328 }
329
GetLimitMaximumExtensionsPerDevice()330 int32_t AppUtils::GetLimitMaximumExtensionsPerDevice()
331 {
332 if (!limitMaximumExtensionsPerDevice_.isLoaded) {
333 limitMaximumExtensionsPerDevice_.value =
334 system::GetIntParameter<int32_t>(LIMIT_MAXIMUM_EXTENSIONS_OF_PER_DEVICE, DEFAULT_MAX_EXT_PER_DEV);
335 limitMaximumExtensionsPerDevice_.isLoaded = true;
336 }
337 TAG_LOGD(AAFwkTag::DEFAULT, "limitMaximumExtensionsPerDevice: %{public}d", limitMaximumExtensionsPerDevice_.value);
338 return limitMaximumExtensionsPerDevice_.value;
339 }
340
GetCacheExtensionTypeList()341 std::string AppUtils::GetCacheExtensionTypeList()
342 {
343 std::string cacheExtAbilityTypeList = system::GetParameter(CACHE_EXTENSION_TYPES, "260");
344 TAG_LOGD(AAFwkTag::DEFAULT, "cacheExtAbilityTypeList is %{public}s", cacheExtAbilityTypeList.c_str());
345 return cacheExtAbilityTypeList;
346 }
347
IsAllowStartAbilityWithoutCallerToken(const std::string & bundleName,const std::string & abilityName)348 bool AppUtils::IsAllowStartAbilityWithoutCallerToken(const std::string& bundleName, const std::string& abilityName)
349 {
350 std::lock_guard lock(startAbilityWithoutCallerTokenMutex_);
351 if (!startAbilityWithoutCallerToken_.isLoaded) {
352 LoadStartAbilityWithoutCallerToken();
353 startAbilityWithoutCallerToken_.isLoaded = true;
354 }
355 TAG_LOGD(AAFwkTag::DEFAULT, "isLoaded: %{public}d", startAbilityWithoutCallerToken_.isLoaded);
356 for (auto &element : startAbilityWithoutCallerToken_.value) {
357 if (bundleName == element.first && abilityName == element.second) {
358 TAG_LOGI(AAFwkTag::DEFAULT, "call");
359 return true;
360 }
361 }
362 return false;
363 }
364
LoadStartAbilityWithoutCallerToken()365 void AppUtils::LoadStartAbilityWithoutCallerToken()
366 {
367 nlohmann::json object;
368 if (!JsonUtils::GetInstance().LoadConfiguration(
369 START_ABILITY_WITHOUT_CALLERTOKEN_PATH, object, START_ABILITY_WITHOUT_CALLERTOKEN)) {
370 TAG_LOGE(AAFwkTag::DEFAULT, "token list failed");
371 return;
372 }
373 if (!object.contains(START_ABILITY_WITHOUT_CALLERTOKEN_TITLE)) {
374 TAG_LOGE(AAFwkTag::DEFAULT, "token config invalid");
375 return;
376 }
377
378 for (auto &item : object.at(START_ABILITY_WITHOUT_CALLERTOKEN_TITLE).items()) {
379 const nlohmann::json& jsonObject = item.value();
380 if (!jsonObject.contains(BUNDLE_NAME) || !jsonObject.at(BUNDLE_NAME).is_string()) {
381 TAG_LOGE(AAFwkTag::DEFAULT, "load bundleName failed");
382 return;
383 }
384 if (!jsonObject.contains(ABILITY_NAME) || !jsonObject.at(ABILITY_NAME).is_string()) {
385 TAG_LOGE(AAFwkTag::DEFAULT, "load abilityName failed");
386 return;
387 }
388 std::string bundleName = jsonObject.at(BUNDLE_NAME).get<std::string>();
389 std::string abilityName = jsonObject.at(ABILITY_NAME).get<std::string>();
390 startAbilityWithoutCallerToken_.value.emplace_back(std::make_pair(bundleName, abilityName));
391 }
392 }
393
MaxChildProcess()394 int32_t AppUtils::MaxChildProcess()
395 {
396 if (!maxChildProcess_.isLoaded) {
397 maxChildProcess_.value =
398 system::GetIntParameter<int32_t>(MAX_CHILD_PROCESS, DEFAULT_MAX_CHILD_PROCESS);
399 maxChildProcess_.isLoaded = true;
400 }
401 TAG_LOGD(AAFwkTag::DEFAULT, "MaxChildProcess: %{public}d", maxChildProcess_.value);
402 return maxChildProcess_.value;
403 }
404 } // namespace AAFwk
405 } // namespace OHOS
406