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