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