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