1 /*
2 * Copyright (c) 2025 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 "start_options_utils.h"
17
18 #include "ability_manager_errors.h"
19 #include "ability_manager_service.h"
20 #include "ability_permission_util.h"
21 #include "ability_record.h"
22 #include "ability_util.h"
23 #include "app_scheduler.h"
24 #include "app_utils.h"
25 #include "hidden_start_utils.h"
26 #include "hitrace_meter.h"
27 #include "process_options.h"
28 #include "permission_verification.h"
29 #include "hilog_tag_wrapper.h"
30 #include "ipc_skeleton.h"
31 #include "process_options.h"
32 #include "scene_board_judgement.h"
33 #include "start_options.h"
34 #include "startup_util.h"
35 #include "want.h"
36
37 namespace OHOS {
38 namespace AAFwk {
39 namespace {
40 constexpr const char* ACTION_CHOOSE = "ohos.want.action.select";
41 constexpr const char* FOUNDATION_PROCESS_NAME = "foundation";
42 }
CheckProcessOptions(const Want & want,const StartOptions & options,int32_t userId)43 int32_t StartOptionsUtils::CheckProcessOptions(const Want &want, const StartOptions &options, int32_t userId)
44 {
45 if (HiddenStartUtils::IsHiddenStart(options)) {
46 return HiddenStartUtils::CheckHiddenStartSupported(options);
47 }
48 if (AbilityPermissionUtil::GetInstance().IsStartSelfUIAbility() &&
49 options.processOptions != nullptr && options.processOptions->isStartFromNDK) {
50 return CheckStartSelfUIAbilityStartOptions(want, options);
51 }
52 return CheckProcessOptionsInner(want, options, userId);
53 }
54
CheckProcessOptionsInner(const Want & want,const StartOptions & options,int32_t userId)55 int32_t StartOptionsUtils::CheckProcessOptionsInner(const Want &want, const StartOptions &options, int32_t userId)
56 {
57 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
58 if (options.processOptions == nullptr ||
59 (!ProcessOptions::IsValidProcessMode(options.processOptions->processMode) &&
60 !options.processOptions->isRestartKeepAlive)) {
61 return ERR_OK;
62 }
63
64 TAG_LOGI(AAFwkTag::ABILITYMGR, "start ability with process options");
65 bool isEnable = AppUtils::GetInstance().IsStartOptionsWithProcessOptions();
66 CHECK_TRUE_RETURN_RET(!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() || !isEnable,
67 ERR_CAPABILITY_NOT_SUPPORT, "not support process options");
68
69 auto element = want.GetElement();
70 CHECK_TRUE_RETURN_RET(element.GetAbilityName().empty() || want.GetAction().compare(ACTION_CHOOSE) == 0,
71 ERR_NOT_ALLOW_IMPLICIT_START, "not allow implicit start");
72
73 if (PermissionVerification::GetInstance()->CheckSpecificSystemAbilityAccessPermission(FOUNDATION_PROCESS_NAME)
74 && options.processOptions->isRestartKeepAlive) {
75 TAG_LOGI(AAFwkTag::ABILITYMGR, "restart keep-alive app.");
76 return ERR_OK;
77 }
78
79 int32_t appIndex = 0;
80 appIndex = !AbilityRuntime::StartupUtil::GetAppIndex(want, appIndex) ? 0 : appIndex;
81 CHECK_TRUE_RETURN_RET(!DelayedSingleton<AbilityManagerService>::GetInstance()->CheckCallingTokenId(
82 element.GetBundleName(), userId, appIndex), ERR_NOT_SELF_APPLICATION, "not self application");
83
84 auto uiAbilityManager = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUIAbilityManagerByUid(
85 IPCSkeleton::GetCallingUid());
86 CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE);
87
88 auto callerPid = IPCSkeleton::GetCallingPid();
89 AppExecFwk::RunningProcessInfo processInfo;
90 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(callerPid, processInfo);
91 CHECK_TRUE_RETURN_RET((ProcessOptions::IsAttachToStatusBarMode(options.processOptions->processMode) &&
92 !uiAbilityManager->IsCallerInStatusBar(processInfo.instanceKey)), ERR_START_OPTIONS_CHECK_FAILED,
93 "not in status bar");
94
95 auto abilityRecords = uiAbilityManager->GetAbilityRecordsByName(element);
96 CHECK_TRUE_RETURN_RET(!abilityRecords.empty() && abilityRecords[0] &&
97 abilityRecords[0]->GetAbilityInfo().launchMode != AppExecFwk::LaunchMode::STANDARD &&
98 abilityRecords[0]->GetAbilityInfo().launchMode != AppExecFwk::LaunchMode::SPECIFIED,
99 ERR_ABILITY_ALREADY_RUNNING, "if not STANDARD or SPECIFIED mode, repeated starts not allowed");
100
101 return ERR_OK;
102 }
103
CheckStartSelfUIAbilityStartOptions(const Want & want,const StartOptions & options)104 int32_t StartOptionsUtils::CheckStartSelfUIAbilityStartOptions(const Want &want, const StartOptions &options)
105 {
106 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
107 if (options.processOptions == nullptr) {
108 return ERR_OK;
109 }
110
111 TAG_LOGI(AAFwkTag::ABILITYMGR, "start ability with process options");
112 bool isEnable = AppUtils::GetInstance().IsStartOptionsWithProcessOptions();
113 CHECK_TRUE_RETURN_RET(!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() || !isEnable,
114 ERR_CAPABILITY_NOT_SUPPORT, "not support process options");
115
116 auto uiAbilityManager = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUIAbilityManagerByUid(
117 IPCSkeleton::GetCallingUid());
118 CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE);
119
120 auto callerPid = IPCSkeleton::GetCallingPid();
121 AppExecFwk::RunningProcessInfo processInfo;
122 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByChildProcessPid(callerPid, processInfo);
123 CHECK_TRUE_RETURN_RET(!uiAbilityManager->IsCallerInStatusBar(processInfo.instanceKey),
124 ERR_START_OPTIONS_CHECK_FAILED, "not in status bar");
125
126 return ERR_OK;
127 }
128 }
129 }