1/* 2 * Copyright (c) 2021-2024 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 "ams_configuration_parameter.h" 17#include <unistd.h> 18#include "app_utils.h" 19#include "config_policy_utils.h" 20#include "hilog_tag_wrapper.h" 21 22namespace OHOS { 23namespace AAFwk { 24namespace { 25constexpr int32_t LOAD_CONFIGURATION_FAILED = -1; 26constexpr int32_t LOAD_CONFIGURATION_SUCCESS = 0; 27constexpr int32_t MAX_RESIDENT_WHITE_LIST_SIZE = 100; 28} 29 30AmsConfigurationParameter::AmsConfigurationParameter() {} 31 32AmsConfigurationParameter &AmsConfigurationParameter::GetInstance() 33{ 34 static AmsConfigurationParameter amsConfiguration; 35 return amsConfiguration; 36} 37 38using json = nlohmann::json; 39 40void AmsConfigurationParameter::Parse() 41{ 42 auto ref = LoadAmsConfiguration(AmsConfig::AMS_CONFIG_FILE_PATH); 43 44 char buf[MAX_PATH_LEN] = { 0 }; 45 char *filePath = GetOneCfgFile(AmsConfig::PICKER_CONFIG_FILE_PATH, buf, MAX_PATH_LEN); 46 if (filePath == nullptr || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) { 47 TAG_LOGE(AAFwkTag::ABILITYMGR, "Can not get config file"); 48 LoadUIExtensionPickerConfig(AmsConfig::PICKER_CONFIG_FILE_PATH_DEFAULT); 49 return; 50 } 51 std::string customConfig = filePath; 52 TAG_LOGI(AAFwkTag::ABILITYMGR, "file path: %{private}s", customConfig.c_str()); 53 LoadUIExtensionPickerConfig(customConfig); 54 TAG_LOGI(AAFwkTag::ABILITYMGR, "load config ref : %{private}d", ref); 55} 56 57bool AmsConfigurationParameter::NonConfigFile() const 58{ 59 return nonConfigFile_; 60} 61 62int AmsConfigurationParameter::GetMissionSaveTime() const 63{ 64 return missionSaveTime_; 65} 66 67std::string AmsConfigurationParameter::GetOrientation() const 68{ 69 return orientation_; 70} 71 72int AmsConfigurationParameter::GetANRTimeOutTime() const 73{ 74 return anrTime_; 75} 76 77int AmsConfigurationParameter::GetAMSTimeOutTime() const 78{ 79 return amsTime_; 80} 81 82int AmsConfigurationParameter::GetMaxRestartNum(bool isRootLauncher) const 83{ 84 return (isRootLauncher ? maxRootLauncherRestartNum_ : maxResidentRestartNum_); 85} 86 87int AmsConfigurationParameter::GetRestartIntervalTime() const 88{ 89 return restartIntervalTime_; 90} 91 92int AmsConfigurationParameter::GetBootAnimationTimeoutTime() const 93{ 94 return bootAnimationTime_; 95} 96 97int AmsConfigurationParameter::GetAppStartTimeoutTime() const 98{ 99 return timeoutUnitTime_ * AppUtils::GetInstance().GetTimeoutUnitTimeRatio(); 100} 101 102void AmsConfigurationParameter::SetPickerJsonObject(nlohmann::json Object) 103{ 104 if (Object.contains(AmsConfig::PICKER_CONFIGURATION)) { 105 pickerJsonObject_ = Object.at(AmsConfig::PICKER_CONFIGURATION); 106 } 107} 108 109nlohmann::json AmsConfigurationParameter::GetPickerJsonObject() const 110{ 111 return pickerJsonObject_; 112} 113 114const std::map<std::string, std::string>& AmsConfigurationParameter::GetPickerMap() const 115{ 116 return picker_; 117} 118 119void AmsConfigurationParameter::LoadUIExtensionPickerConfig(const std::string &filePath) 120{ 121 TAG_LOGI(AAFwkTag::ABILITYMGR, "%{public}s", __func__); 122 if (filePath.empty()) { 123 TAG_LOGE(AAFwkTag::ABILITYMGR, "empty file path"); 124 return; 125 } 126 127 if (access(filePath.c_str(), F_OK) != 0) { 128 TAG_LOGE(AAFwkTag::ABILITYMGR, "can not access the file: %{private}s", filePath.c_str()); 129 return; 130 } 131 std::ifstream inFile; 132 inFile.open(filePath, std::ios::in); 133 if (!inFile.is_open()) { 134 TAG_LOGE(AAFwkTag::ABILITYMGR, "read picker config error"); 135 return; 136 } 137 138 json pickerJson; 139 inFile >> pickerJson; 140 inFile.close(); 141 if (pickerJson.is_discarded()) { 142 TAG_LOGE(AAFwkTag::ABILITYMGR, "json discarded error"); 143 return; 144 } 145 146 if (pickerJson.is_null() || pickerJson.empty()) { 147 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid jsonObj"); 148 return; 149 } 150 151 if (!pickerJson.contains(AmsConfig::UIEATENSION)) { 152 TAG_LOGE(AAFwkTag::ABILITYMGR, "json config not contains the key"); 153 return; 154 } 155 156 if (pickerJson[AmsConfig::UIEATENSION].is_null() || !pickerJson[AmsConfig::UIEATENSION].is_array() 157 || pickerJson[AmsConfig::UIEATENSION].empty()) { 158 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid obj"); 159 return; 160 } 161 162 for (auto extension : pickerJson[AmsConfig::UIEATENSION]) { 163 if (extension[AmsConfig::UIEATENSION_TYPE].is_null() || !extension[AmsConfig::UIEATENSION_TYPE].is_string() 164 || extension[AmsConfig::UIEATENSION_TYPE_PICKER].is_null() 165 || !extension[AmsConfig::UIEATENSION_TYPE_PICKER].is_string()) { 166 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid key or value"); 167 continue; 168 } 169 std::string type = extension[AmsConfig::UIEATENSION_TYPE].get<std::string>(); 170 std::string typePicker = extension[AmsConfig::UIEATENSION_TYPE_PICKER].get<std::string>(); 171 TAG_LOGI(AAFwkTag::ABILITYMGR, "type: %{public}s, typePicker: %{public}s", type.c_str(), typePicker.c_str()); 172 picker_[type] = typePicker; 173 } 174 pickerJson.clear(); 175 TAG_LOGI(AAFwkTag::ABILITYMGR, "read config success"); 176} 177 178int AmsConfigurationParameter::LoadAmsConfiguration(const std::string &filePath) 179{ 180 TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s", __func__); 181 int ret[2] = {0}; 182 if (filePath.empty()) { 183 TAG_LOGE(AAFwkTag::ABILITYMGR, "empty file path"); 184 return READ_FAIL; 185 } 186 187 if (access(filePath.c_str(), F_OK) != 0) { 188 TAG_LOGE(AAFwkTag::ABILITYMGR, "can not access the file: %{private}s", filePath.c_str()); 189 return READ_FAIL; 190 } 191 std::ifstream inFile; 192 inFile.open(filePath, std::ios::in); 193 if (!inFile.is_open()) { 194 TAG_LOGI(AAFwkTag::ABILITYMGR, "error"); 195 nonConfigFile_ = true; 196 return READ_FAIL; 197 } 198 199 json amsJson; 200 inFile >> amsJson; 201 if (amsJson.is_discarded()) { 202 TAG_LOGI(AAFwkTag::ABILITYMGR, "json discarded error ..."); 203 nonConfigFile_ = true; 204 inFile.close(); 205 return READ_JSON_FAIL; 206 } 207 208 ret[0] = LoadAppConfigurationForStartUpService(amsJson); 209 if (ret[0] != 0) { 210 TAG_LOGE(AAFwkTag::ABILITYMGR, "LoadAppConfigurationForStartUpService return error"); 211 } 212 213 ret[1] = LoadAppConfigurationForMemoryThreshold(amsJson); 214 if (ret[1] != 0) { 215 TAG_LOGE(AAFwkTag::ABILITYMGR, "LoadAppConfigurationForMemoryThreshold return error"); 216 } 217 218 LoadSystemConfiguration(amsJson); 219 LoadBackToCallerConfig(amsJson); 220 LoadSupportSCBCrashRebootConfig(amsJson); 221 SetPickerJsonObject(amsJson); 222 LoadResidentWhiteListConfig(amsJson); 223 amsJson.clear(); 224 inFile.close(); 225 226 for (const auto& i : ret) { 227 if (i != 0) { 228 TAG_LOGE(AAFwkTag::ABILITYMGR, "json no have service item ..."); 229 return READ_JSON_FAIL; 230 } 231 } 232 233 TAG_LOGI(AAFwkTag::ABILITYMGR, "reading ability manager service config success"); 234 return READ_OK; 235} 236 237int AmsConfigurationParameter::LoadAppConfigurationForStartUpService(nlohmann::json& Object) 238{ 239 if (!Object.contains(AmsConfig::SERVICE_ITEM_AMS)) { 240 return LOAD_CONFIGURATION_FAILED; 241 } 242 UpdateStartUpServiceConfigInteger(Object, AmsConfig::MISSION_SAVE_TIME, missionSaveTime_); 243 UpdateStartUpServiceConfigInteger(Object, AmsConfig::APP_NOT_RESPONSE_PROCESS_TIMEOUT_TIME, anrTime_); 244 UpdateStartUpServiceConfigInteger(Object, AmsConfig::AMS_TIMEOUT_TIME, amsTime_); 245 UpdateStartUpServiceConfigInteger(Object, AmsConfig::ROOT_LAUNCHER_RESTART_MAX, maxRootLauncherRestartNum_); 246 UpdateStartUpServiceConfigInteger(Object, AmsConfig::RESIDENT_RESTART_MAX, maxResidentRestartNum_); 247 UpdateStartUpServiceConfigInteger(Object, AmsConfig::RESTART_INTERVAL_TIME, restartIntervalTime_); 248 UpdateStartUpServiceConfigInteger(Object, AmsConfig::BOOT_ANIMATION_TIMEOUT_TIME, bootAnimationTime_); 249 UpdateStartUpServiceConfigInteger(Object, AmsConfig::TIMEOUT_UNIT_TIME, timeoutUnitTime_); 250 UpdateStartUpServiceConfigInteger(Object, AmsConfig::MULTI_USER_TYPE, multiUserType_); 251 return LOAD_CONFIGURATION_SUCCESS; 252} 253 254int AmsConfigurationParameter::LoadAppConfigurationForMemoryThreshold(nlohmann::json &Object) 255{ 256 int ret = 0; 257 if (!Object.contains("memorythreshold")) { 258 TAG_LOGE(AAFwkTag::ABILITYMGR, "LoadAppConfigurationForMemoryThreshold return error"); 259 ret = -1; 260 } 261 262 return ret; 263} 264 265int AmsConfigurationParameter::LoadSystemConfiguration(nlohmann::json& Object) 266{ 267 if (Object.contains(AmsConfig::SYSTEM_CONFIGURATION) && 268 Object.at(AmsConfig::SYSTEM_CONFIGURATION).contains(AmsConfig::SYSTEM_ORIENTATION) && 269 Object.at(AmsConfig::SYSTEM_CONFIGURATION).at(AmsConfig::SYSTEM_ORIENTATION).is_string()) { 270 orientation_ = Object.at(AmsConfig::SYSTEM_CONFIGURATION).at(AmsConfig::SYSTEM_ORIENTATION).get<std::string>(); 271 return READ_OK; 272 } 273 274 return READ_FAIL; 275} 276 277int32_t AmsConfigurationParameter::LoadBackToCallerConfig(nlohmann::json& Object) 278{ 279 TAG_LOGI(AAFwkTag::ABILITYMGR, "load backTocaller config"); 280 if (Object.contains(AmsConfig::SUPPORT_BACK_TO_CALLER) && 281 Object.at(AmsConfig::SUPPORT_BACK_TO_CALLER).is_boolean()) { 282 supportBackToCaller_ = Object.at(AmsConfig::SUPPORT_BACK_TO_CALLER).get<bool>(); 283 return READ_OK; 284 } 285 TAG_LOGE(AAFwkTag::ABILITYMGR, "load backTocaller failed"); 286 return READ_FAIL; 287} 288 289bool AmsConfigurationParameter::IsSupportBackToCaller() const 290{ 291 return supportBackToCaller_; 292} 293 294int32_t AmsConfigurationParameter::LoadSupportSCBCrashRebootConfig(nlohmann::json& Object) 295{ 296 TAG_LOGI(AAFwkTag::ABILITYMGR, "load scb_crash_reboot_config config"); 297 if (Object.contains(AmsConfig::SUPPORT_SCB_CRASH_REBOOT) && 298 Object.at(AmsConfig::SUPPORT_SCB_CRASH_REBOOT).is_boolean()) { 299 supportSceneboardCrashReboot_ = Object.at(AmsConfig::SUPPORT_SCB_CRASH_REBOOT).get<bool>(); 300 return READ_OK; 301 } 302 TAG_LOGE(AAFwkTag::ABILITYMGR, "load scb_crash_reboot_config failed"); 303 return READ_FAIL; 304} 305 306bool AmsConfigurationParameter::IsSupportSCBCrashReboot() const 307{ 308 return supportSceneboardCrashReboot_; 309} 310 311bool AmsConfigurationParameter::CheckServiceConfigEnable(nlohmann::json& Object, const std::string &configName, 312 JsonValueType type) 313{ 314 if (Object.contains(AmsConfig::SERVICE_ITEM_AMS) && 315 Object.at(AmsConfig::SERVICE_ITEM_AMS).contains(configName)) { 316 switch (type) { 317 case JsonValueType::NUMBER: { 318 return Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).is_number(); 319 } 320 case JsonValueType::STRING: { 321 return Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).is_string(); 322 } 323 case JsonValueType::BOOLEAN: { 324 return Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).is_boolean(); 325 } 326 default: { 327 return false; 328 } 329 } 330 } 331 return false; 332} 333 334void AmsConfigurationParameter::UpdateStartUpServiceConfigInteger(nlohmann::json& Object, 335 const std::string &configName, int32_t &value) 336{ 337 if (CheckServiceConfigEnable(Object, configName, JsonValueType::NUMBER)) { 338 value = Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).get<int>(); 339 } 340} 341 342void AmsConfigurationParameter::UpdateStartUpServiceConfigString(nlohmann::json& Object, 343 const std::string &configName, std::string &value) 344{ 345 if (CheckServiceConfigEnable(Object, configName, JsonValueType::STRING)) { 346 value = Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).get<std::string>(); 347 } 348} 349 350int AmsConfigurationParameter::MultiUserType() const 351{ 352 return multiUserType_; 353} 354 355void AmsConfigurationParameter::LoadResidentWhiteListConfig(nlohmann::json& Object) 356{ 357 if (!Object.contains(AmsConfig::RESIDENT_WHITE_LIST)) { 358 TAG_LOGI(AAFwkTag::ABILITYMGR, "no normal_resident_apps"); 359 return; 360 } 361 const auto &whiteListJson = Object.at(AmsConfig::RESIDENT_WHITE_LIST); 362 if (!whiteListJson.is_array()) { 363 TAG_LOGI(AAFwkTag::ABILITYMGR, "normal_resident_apps type error"); 364 return; 365 } 366 auto size = whiteListJson.size(); 367 if (size > MAX_RESIDENT_WHITE_LIST_SIZE) { 368 size = MAX_RESIDENT_WHITE_LIST_SIZE; 369 } 370 for (decltype(size) i = 0; i < size; i++) { 371 const auto &item = whiteListJson.at(i); 372 if (item.is_string()) { 373 residentWhiteList_.push_back(item.get<std::string>()); 374 } 375 } 376} 377 378bool AmsConfigurationParameter::InResidentWhiteList(const std::string &bundleName) const 379{ 380 if (residentWhiteList_.empty()) { 381 return true; 382 } 383 384 for (const auto &item: residentWhiteList_) { 385 if (bundleName == item) { 386 return true; 387 } 388 } 389 return false; 390} 391 392const std::vector<std::string> &AmsConfigurationParameter::GetResidentWhiteList() const 393{ 394 return residentWhiteList_; 395} 396} // namespace AAFwk 397} // namespace OHOS 398