• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }