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, "file path: %{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, "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 int ret[2] = {0};
181 if (filePath.empty()) {
182 TAG_LOGE(AAFwkTag::ABILITYMGR, "empty file path");
183 return READ_FAIL;
184 }
185
186 if (access(filePath.c_str(), F_OK) != 0) {
187 TAG_LOGE(AAFwkTag::ABILITYMGR, "can not access the file: %{private}s", filePath.c_str());
188 return READ_FAIL;
189 }
190 std::ifstream inFile;
191 inFile.open(filePath, std::ios::in);
192 if (!inFile.is_open()) {
193 TAG_LOGI(AAFwkTag::ABILITYMGR, "error");
194 nonConfigFile_ = true;
195 return READ_FAIL;
196 }
197
198 json amsJson;
199 inFile >> amsJson;
200 if (amsJson.is_discarded()) {
201 TAG_LOGI(AAFwkTag::ABILITYMGR, "json discarded error ...");
202 nonConfigFile_ = true;
203 inFile.close();
204 return READ_JSON_FAIL;
205 }
206
207 ret[0] = LoadAppConfigurationForStartUpService(amsJson);
208 if (ret[0] != 0) {
209 TAG_LOGE(AAFwkTag::ABILITYMGR, "LoadAppConfigurationForStartUpService return error");
210 }
211
212 ret[1] = LoadAppConfigurationForMemoryThreshold(amsJson);
213 if (ret[1] != 0) {
214 TAG_LOGE(AAFwkTag::ABILITYMGR, "LoadAppConfigurationForMemoryThreshold return error");
215 }
216
217 LoadSystemConfiguration(amsJson);
218 LoadBackToCallerConfig(amsJson);
219 LoadSupportSCBCrashRebootConfig(amsJson);
220 LoadSupportAAKillWithReasonConfig(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
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 UpdateStartUpServiceConfigInteger(Object, AmsConfig::CUSTOM_SANDBOX_FEATURE, supportCustomSandbox_);
252 return LOAD_CONFIGURATION_SUCCESS;
253 }
254
LoadAppConfigurationForMemoryThreshold(nlohmann::json & Object)255 int AmsConfigurationParameter::LoadAppConfigurationForMemoryThreshold(nlohmann::json &Object)
256 {
257 int ret = 0;
258 if (!Object.contains("memorythreshold")) {
259 TAG_LOGE(AAFwkTag::ABILITYMGR, "LoadAppConfigurationForMemoryThreshold return error");
260 ret = -1;
261 }
262
263 return ret;
264 }
265
LoadSystemConfiguration(nlohmann::json & Object)266 int AmsConfigurationParameter::LoadSystemConfiguration(nlohmann::json& Object)
267 {
268 if (Object.contains(AmsConfig::SYSTEM_CONFIGURATION) &&
269 Object.at(AmsConfig::SYSTEM_CONFIGURATION).contains(AmsConfig::SYSTEM_ORIENTATION) &&
270 Object.at(AmsConfig::SYSTEM_CONFIGURATION).at(AmsConfig::SYSTEM_ORIENTATION).is_string()) {
271 orientation_ = Object.at(AmsConfig::SYSTEM_CONFIGURATION).at(AmsConfig::SYSTEM_ORIENTATION).get<std::string>();
272 return READ_OK;
273 }
274
275 return READ_FAIL;
276 }
277
LoadBackToCallerConfig(nlohmann::json & Object)278 int32_t AmsConfigurationParameter::LoadBackToCallerConfig(nlohmann::json& Object)
279 {
280 TAG_LOGI(AAFwkTag::ABILITYMGR, "load backTocaller config");
281 if (Object.contains(AmsConfig::SUPPORT_BACK_TO_CALLER) &&
282 Object.at(AmsConfig::SUPPORT_BACK_TO_CALLER).is_boolean()) {
283 supportBackToCaller_ = Object.at(AmsConfig::SUPPORT_BACK_TO_CALLER).get<bool>();
284 return READ_OK;
285 }
286 TAG_LOGE(AAFwkTag::ABILITYMGR, "load backTocaller failed");
287 return READ_FAIL;
288 }
289
LoadSupportAAKillWithReasonConfig(nlohmann::json & Object)290 int32_t AmsConfigurationParameter::LoadSupportAAKillWithReasonConfig(nlohmann::json& Object)
291 {
292 TAG_LOGI(AAFwkTag::ABILITYMGR, "load SupportAAKillWithReason config");
293 if (Object.contains(AmsConfig::SUPPORT_AA_KILL_WITH_REASON) &&
294 Object.at(AmsConfig::SUPPORT_AA_KILL_WITH_REASON).is_boolean()) {
295 supportAAKillWithReason_ = Object.at(AmsConfig::SUPPORT_AA_KILL_WITH_REASON).get<bool>();
296 return READ_OK;
297 }
298 TAG_LOGE(AAFwkTag::ABILITYMGR, "load SupportAAKillWithReason failed");
299 return READ_FAIL;
300 }
301
IsSupportBackToCaller() const302 bool AmsConfigurationParameter::IsSupportBackToCaller() const
303 {
304 return supportBackToCaller_;
305 }
306
IsSupportAAKillWithReason() const307 bool AmsConfigurationParameter::IsSupportAAKillWithReason() const
308 {
309 return supportAAKillWithReason_;
310 }
311
LoadSupportSCBCrashRebootConfig(nlohmann::json & Object)312 int32_t AmsConfigurationParameter::LoadSupportSCBCrashRebootConfig(nlohmann::json& Object)
313 {
314 TAG_LOGI(AAFwkTag::ABILITYMGR, "load scb_crash_reboot_config config");
315 if (Object.contains(AmsConfig::SUPPORT_SCB_CRASH_REBOOT) &&
316 Object.at(AmsConfig::SUPPORT_SCB_CRASH_REBOOT).is_boolean()) {
317 supportSceneboardCrashReboot_ = Object.at(AmsConfig::SUPPORT_SCB_CRASH_REBOOT).get<bool>();
318 return READ_OK;
319 }
320 TAG_LOGE(AAFwkTag::ABILITYMGR, "load scb_crash_reboot_config failed");
321 return READ_FAIL;
322 }
323
IsSupportSCBCrashReboot() const324 bool AmsConfigurationParameter::IsSupportSCBCrashReboot() const
325 {
326 return supportSceneboardCrashReboot_;
327 }
328
CheckServiceConfigEnable(nlohmann::json & Object,const std::string & configName,JsonValueType type)329 bool AmsConfigurationParameter::CheckServiceConfigEnable(nlohmann::json& Object, const std::string &configName,
330 JsonValueType type)
331 {
332 if (Object.contains(AmsConfig::SERVICE_ITEM_AMS) &&
333 Object.at(AmsConfig::SERVICE_ITEM_AMS).contains(configName)) {
334 switch (type) {
335 case JsonValueType::NUMBER: {
336 return Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).is_number();
337 }
338 case JsonValueType::STRING: {
339 return Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).is_string();
340 }
341 case JsonValueType::BOOLEAN: {
342 return Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).is_boolean();
343 }
344 default: {
345 return false;
346 }
347 }
348 }
349 return false;
350 }
351
UpdateStartUpServiceConfigInteger(nlohmann::json & Object,const std::string & configName,int32_t & value)352 void AmsConfigurationParameter::UpdateStartUpServiceConfigInteger(nlohmann::json& Object,
353 const std::string &configName, int32_t &value)
354 {
355 if (CheckServiceConfigEnable(Object, configName, JsonValueType::NUMBER)) {
356 value = Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).get<int>();
357 }
358 }
359
UpdateStartUpServiceConfigString(nlohmann::json & Object,const std::string & configName,std::string & value)360 void AmsConfigurationParameter::UpdateStartUpServiceConfigString(nlohmann::json& Object,
361 const std::string &configName, std::string &value)
362 {
363 if (CheckServiceConfigEnable(Object, configName, JsonValueType::STRING)) {
364 value = Object.at(AmsConfig::SERVICE_ITEM_AMS).at(configName).get<std::string>();
365 }
366 }
367
MultiUserType() const368 int AmsConfigurationParameter::MultiUserType() const
369 {
370 return multiUserType_;
371 }
372
CustomSandbox() const373 int AmsConfigurationParameter::CustomSandbox() const
374 {
375 return supportCustomSandbox_;
376 }
377
LoadResidentWhiteListConfig(nlohmann::json & Object)378 void AmsConfigurationParameter::LoadResidentWhiteListConfig(nlohmann::json& Object)
379 {
380 if (!Object.contains(AmsConfig::RESIDENT_WHITE_LIST)) {
381 TAG_LOGI(AAFwkTag::ABILITYMGR, "no normal_resident_apps");
382 return;
383 }
384 const auto &whiteListJson = Object.at(AmsConfig::RESIDENT_WHITE_LIST);
385 if (!whiteListJson.is_array()) {
386 TAG_LOGI(AAFwkTag::ABILITYMGR, "normal_resident_apps type error");
387 return;
388 }
389 auto size = whiteListJson.size();
390 if (size > MAX_RESIDENT_WHITE_LIST_SIZE) {
391 size = MAX_RESIDENT_WHITE_LIST_SIZE;
392 }
393 for (decltype(size) i = 0; i < size; i++) {
394 const auto &item = whiteListJson.at(i);
395 if (item.is_string()) {
396 residentWhiteList_.push_back(item.get<std::string>());
397 }
398 }
399 }
400
InResidentWhiteList(const std::string & bundleName) const401 bool AmsConfigurationParameter::InResidentWhiteList(const std::string &bundleName) const
402 {
403 if (residentWhiteList_.empty()) {
404 return true;
405 }
406
407 for (const auto &item: residentWhiteList_) {
408 if (bundleName == item) {
409 return true;
410 }
411 }
412 return false;
413 }
414
GetResidentWhiteList() const415 const std::vector<std::string> &AmsConfigurationParameter::GetResidentWhiteList() const
416 {
417 return residentWhiteList_;
418 }
419 } // namespace AAFwk
420 } // namespace OHOS
421