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
22 namespace OHOS {
23 namespace AAFwk {
24 namespace {
25 constexpr int32_t LOAD_CONFIGURATION_FAILED = -1;
26 constexpr int32_t LOAD_CONFIGURATION_SUCCESS = 0;
27 constexpr int32_t MAX_RESIDENT_WHITE_LIST_SIZE = 100;
28 }
29
AmsConfigurationParameter()30 AmsConfigurationParameter::AmsConfigurationParameter() {}
31
GetInstance()32 AmsConfigurationParameter &AmsConfigurationParameter::GetInstance()
33 {
34 static AmsConfigurationParameter amsConfiguration;
35 return amsConfiguration;
36 }
37
38 using json = nlohmann::json;
39
Parse()40 void 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, "The configuration file path is :%{private}s", customConfig.c_str());
53 LoadUIExtensionPickerConfig(customConfig);
54 TAG_LOGI(AAFwkTag::ABILITYMGR, "load config ref : %{private}d", ref);
55 }
56
NonConfigFile() const57 bool AmsConfigurationParameter::NonConfigFile() const
58 {
59 return nonConfigFile_;
60 }
61
GetMissionSaveTime() const62 int AmsConfigurationParameter::GetMissionSaveTime() const
63 {
64 return missionSaveTime_;
65 }
66
GetOrientation() const67 std::string AmsConfigurationParameter::GetOrientation() const
68 {
69 return orientation_;
70 }
71
GetANRTimeOutTime() const72 int AmsConfigurationParameter::GetANRTimeOutTime() const
73 {
74 return anrTime_;
75 }
76
GetAMSTimeOutTime() const77 int AmsConfigurationParameter::GetAMSTimeOutTime() const
78 {
79 return amsTime_;
80 }
81
GetMaxRestartNum(bool isRootLauncher) const82 int AmsConfigurationParameter::GetMaxRestartNum(bool isRootLauncher) const
83 {
84 return (isRootLauncher ? maxRootLauncherRestartNum_ : maxResidentRestartNum_);
85 }
86
GetRestartIntervalTime() const87 int AmsConfigurationParameter::GetRestartIntervalTime() const
88 {
89 return restartIntervalTime_;
90 }
91
GetBootAnimationTimeoutTime() const92 int AmsConfigurationParameter::GetBootAnimationTimeoutTime() const
93 {
94 return bootAnimationTime_;
95 }
96
GetAppStartTimeoutTime() const97 int AmsConfigurationParameter::GetAppStartTimeoutTime() const
98 {
99 return timeoutUnitTime_ * AppUtils::GetInstance().GetTimeoutUnitTimeRatio();
100 }
101
SetPickerJsonObject(nlohmann::json Object)102 void AmsConfigurationParameter::SetPickerJsonObject(nlohmann::json Object)
103 {
104 if (Object.contains(AmsConfig::PICKER_CONFIGURATION)) {
105 pickerJsonObject_ = Object.at(AmsConfig::PICKER_CONFIGURATION);
106 }
107 }
108
GetPickerJsonObject() const109 nlohmann::json AmsConfigurationParameter::GetPickerJsonObject() const
110 {
111 return pickerJsonObject_;
112 }
113
GetPickerMap() const114 const std::map<std::string, std::string>& AmsConfigurationParameter::GetPickerMap() const
115 {
116 return picker_;
117 }
118
LoadUIExtensionPickerConfig(const std::string & filePath)119 void AmsConfigurationParameter::LoadUIExtensionPickerConfig(const std::string &filePath)
120 {
121 TAG_LOGI(AAFwkTag::ABILITYMGR, "%{public}s", __func__);
122 if (filePath.empty()) {
123 TAG_LOGE(AAFwkTag::ABILITYMGR, "the file is not existed due to 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
LoadAmsConfiguration(const std::string & filePath)178 int 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, "the file is not existed due to 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, "Read ability manager service config 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, "read ams config success!");
234 return READ_OK;
235 }
236
LoadAppConfigurationForStartUpService(nlohmann::json & Object)237 int 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
LoadAppConfigurationForMemoryThreshold(nlohmann::json & Object)254 int 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
LoadSystemConfiguration(nlohmann::json & Object)265 int 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
LoadBackToCallerConfig(nlohmann::json & Object)277 int32_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
IsSupportBackToCaller() const289 bool AmsConfigurationParameter::IsSupportBackToCaller() const
290 {
291 return supportBackToCaller_;
292 }
293
LoadSupportSCBCrashRebootConfig(nlohmann::json & Object)294 int32_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
IsSupportSCBCrashReboot() const306 bool AmsConfigurationParameter::IsSupportSCBCrashReboot() const
307 {
308 return supportSceneboardCrashReboot_;
309 }
310
CheckServiceConfigEnable(nlohmann::json & Object,const std::string & configName,JsonValueType type)311 bool 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
UpdateStartUpServiceConfigInteger(nlohmann::json & Object,const std::string & configName,int32_t & value)334 void 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
UpdateStartUpServiceConfigString(nlohmann::json & Object,const std::string & configName,std::string & value)342 void 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
MultiUserType() const350 int AmsConfigurationParameter::MultiUserType() const
351 {
352 return multiUserType_;
353 }
354
LoadResidentWhiteListConfig(nlohmann::json & Object)355 void 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
InResidentWhiteList(const std::string & bundleName) const378 bool 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
GetResidentWhiteList() const392 const std::vector<std::string> &AmsConfigurationParameter::GetResidentWhiteList() const
393 {
394 return residentWhiteList_;
395 }
396 } // namespace AAFwk
397 } // namespace OHOS
398