• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "interceptor/ability_jump_interceptor.h"
17 
18 #include "ability_util.h"
19 #include "accesstoken_kit.h"
20 #include "hitrace_meter.h"
21 #include "permission_constants.h"
22 #include "start_ability_utils.h"
23 #include "system_dialog_scheduler.h"
24 
25 namespace OHOS {
26 namespace AAFwk {
27 namespace {
28 constexpr const char* JUMP_DIALOG_CALLER_BUNDLE_NAME = "interceptor_callerBundleName";
29 constexpr const char* JUMP_DIALOG_CALLER_MODULE_NAME = "interceptor_callerModuleName";
30 constexpr const char* JUMP_DIALOG_CALLER_LABEL_ID = "interceptor_callerLabelId";
31 constexpr const char* JUMP_DIALOG_TARGET_MODULE_NAME = "interceptor_targetModuleName";
32 constexpr const char* JUMP_DIALOG_TARGET_LABEL_ID = "interceptor_targetLabelId";
33 }
DoProcess(AbilityInterceptorParam param)34 ErrCode AbilityJumpInterceptor::DoProcess(AbilityInterceptorParam param)
35 {
36     if (!param.isWithUI) {
37         TAG_LOGI(AAFwkTag::ABILITYMGR, "startup not foreground");
38         return ERR_OK;
39     }
40     bool isStartIncludeAtomicService = AbilityUtil::IsStartIncludeAtomicService(param.want, param.userId);
41     if (isStartIncludeAtomicService) {
42         TAG_LOGI(AAFwkTag::ABILITYMGR, "startup atomic service");
43         return ERR_OK;
44     }
45     // get bms
46     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
47     CHECK_POINTER_AND_RETURN(bundleMgrHelper, ERR_OK);
48     AppExecFwk::AbilityInfo targetAbilityInfo;
49     if (StartAbilityUtils::startAbilityInfo != nullptr &&
50         StartAbilityUtils::startAbilityInfo->abilityInfo.bundleName == param.want.GetBundle() &&
51         StartAbilityUtils::startAbilityInfo->abilityInfo.name == param.want.GetElement().GetAbilityName()) {
52         targetAbilityInfo = StartAbilityUtils::startAbilityInfo->abilityInfo;
53     } else {
54         TAG_LOGD(AAFwkTag::ABILITYMGR, "abilityName: %{public}s, userId: %{public}d",
55             param.want.GetElement().GetAbilityName().c_str(), param.userId);
56         IN_PROCESS_CALL_WITHOUT_RET(bundleMgrHelper->QueryAbilityInfo(param.want,
57             AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, param.userId, targetAbilityInfo));
58     }
59     if (targetAbilityInfo.type != AppExecFwk::AbilityType::PAGE) {
60         TAG_LOGI(AAFwkTag::ABILITYMGR,
61             "no page Ability,type:%{public}d", targetAbilityInfo.type);
62         return ERR_OK;
63     }
64     AppExecFwk::AppJumpControlRule controlRule;
65     if (CheckControl(bundleMgrHelper, param.want, param.userId, controlRule)) {
66 #ifdef SUPPORT_GRAPHICS
67         TAG_LOGI(AAFwkTag::ABILITYMGR, "intercept app jump,caller:%{public}s, target:%{public}s",
68             controlRule.callerPkg.c_str(), controlRule.targetPkg.c_str());
69         auto sysDialogScheduler = DelayedSingleton<SystemDialogScheduler>::GetInstance();
70         Want targetWant = param.want;
71         CHECK_POINTER_AND_RETURN(sysDialogScheduler, ERR_INVALID_VALUE);
72         Want dialogWant = sysDialogScheduler->GetJumpInterceptorDialogWant(targetWant);
73         AbilityUtil::ParseJumpInterceptorWant(dialogWant, controlRule.callerPkg);
74         LoadAppLabelInfo(dialogWant, controlRule, param.userId);
75         int ret = IN_PROCESS_CALL(AbilityManagerClient::GetInstance()->StartAbility(dialogWant,
76             param.requestCode, param.userId));
77         if (ret != ERR_OK) {
78             TAG_LOGI(AAFwkTag::ABILITYMGR, "appInterceptor Dialog StartAbility error, ret:%{public}d", ret);
79             return ret;
80         }
81 #endif
82         return ERR_APP_JUMP_INTERCEPTOR_STATUS;
83     }
84     return ERR_OK;
85 }
86 
CheckControl(std::shared_ptr<AppExecFwk::BundleMgrHelper> & bundleMgrHelper,const Want & want,int32_t userId,AppExecFwk::AppJumpControlRule & controlRule)87 bool AbilityJumpInterceptor::CheckControl(std::shared_ptr<AppExecFwk::BundleMgrHelper> &bundleMgrHelper,
88     const Want &want, int32_t userId, AppExecFwk::AppJumpControlRule &controlRule)
89 {
90     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
91     int callerUid = IPCSkeleton::GetCallingUid();
92     std::string callerBundleName;
93     auto result = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerUid, callerBundleName));
94     std::string targetBundleName = want.GetBundle();
95     controlRule.callerPkg = callerBundleName;
96     controlRule.targetPkg = targetBundleName;
97     if (result != ERR_OK) {
98         TAG_LOGE(AAFwkTag::ABILITYMGR, "getBundleName failed");
99         return false;
100     }
101     if (controlRule.callerPkg.empty() || controlRule.targetPkg.empty()) {
102         TAG_LOGI(AAFwkTag::ABILITYMGR, "explicit startup");
103         return false;
104     }
105     if (controlRule.callerPkg == controlRule.targetPkg) {
106         TAG_LOGI(AAFwkTag::ABILITYMGR, "jump within the same app");
107         return false;
108     }
109     if (CheckIfJumpExempt(controlRule, userId)) {
110         TAG_LOGI(AAFwkTag::ABILITYMGR, "jump to system/exempt apps");
111         return false;
112     }
113     // get disposed status
114     auto appControlMgr = bundleMgrHelper->GetAppControlProxy();
115     if (appControlMgr == nullptr) {
116         TAG_LOGE(AAFwkTag::ABILITYMGR, "null appControlMgr");
117         return false;
118     }
119 
120     if (IN_PROCESS_CALL(appControlMgr->GetAppJumpControlRule(callerBundleName, targetBundleName,
121         userId, controlRule)) != ERR_OK) {
122         TAG_LOGI(AAFwkTag::ABILITYMGR, "no jump rule");
123         return true;
124     }
125     TAG_LOGI(AAFwkTag::ABILITYMGR, "Get appJumpControlRule, jumpMode:%d.", controlRule.jumpMode);
126     return controlRule.jumpMode != AppExecFwk::AbilityJumpMode::DIRECT;
127 }
128 
CheckIfJumpExempt(AppExecFwk::AppJumpControlRule & controlRule,int32_t userId)129 bool AbilityJumpInterceptor::CheckIfJumpExempt(AppExecFwk::AppJumpControlRule &controlRule, int32_t userId)
130 {
131     if (CheckIfExemptByBundleName(controlRule.callerPkg,
132         PermissionConstants::PERMISSION_EXEMPT_AS_CALLER, userId)) {
133         TAG_LOGI(AAFwkTag::ABILITYMGR, "jump from exempt caller app");
134         return true;
135     }
136     if (CheckIfExemptByBundleName(controlRule.targetPkg,
137         PermissionConstants::PERMISSION_EXEMPT_AS_TARGET, userId)) {
138         TAG_LOGI(AAFwkTag::ABILITYMGR, "jump to exempt app");
139         return true;
140     }
141     TAG_LOGI(AAFwkTag::ABILITYMGR, "third-party apps to third-party apps");
142     return false;
143 }
144 
CheckIfExemptByBundleName(const std::string & bundleName,const std::string & permission,int32_t userId)145 bool AbilityJumpInterceptor::CheckIfExemptByBundleName(const std::string &bundleName,
146     const std::string &permission, int32_t userId)
147 {
148     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
149     AppExecFwk::ApplicationInfo appInfo;
150     if (!StartAbilityUtils::GetApplicationInfo(bundleName, userId, appInfo)) {
151         TAG_LOGE(AAFwkTag::ABILITYMGR, "getAppInfo failed");
152         return false;
153     }
154 
155     if (appInfo.isSystemApp) {
156         TAG_LOGI(AAFwkTag::ABILITYMGR, "system app, bundle:%{public}s", bundleName.c_str());
157         return true;
158     }
159     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(appInfo.accessTokenId, permission, false);
160     if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) {
161         TAG_LOGD(AAFwkTag::ABILITYMGR, "PERMISSION_DENIED.");
162         return false;
163     }
164     TAG_LOGI(AAFwkTag::ABILITYMGR,
165         "bundle:%{public}s verify permission:%{public}s succeed", bundleName.c_str(), permission.c_str());
166     return true;
167 }
168 
LoadAppLabelInfo(Want & want,AppExecFwk::AppJumpControlRule & controlRule,int32_t userId)169 bool AbilityJumpInterceptor::LoadAppLabelInfo(Want &want,
170     AppExecFwk::AppJumpControlRule &controlRule, int32_t userId)
171 {
172     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
173     AppExecFwk::ApplicationInfo callerAppInfo;
174     StartAbilityUtils::GetApplicationInfo(controlRule.callerPkg, userId, callerAppInfo);
175     AppExecFwk::ApplicationInfo targetAppInfo;
176     StartAbilityUtils::GetApplicationInfo(controlRule.targetPkg, userId, targetAppInfo);
177     want.SetParam(JUMP_DIALOG_CALLER_BUNDLE_NAME, controlRule.callerPkg);
178     want.SetParam(JUMP_DIALOG_CALLER_MODULE_NAME, callerAppInfo.labelResource.moduleName);
179     want.SetParam(JUMP_DIALOG_CALLER_LABEL_ID, static_cast<long long>(callerAppInfo.labelId));
180     want.SetParam(JUMP_DIALOG_TARGET_MODULE_NAME, targetAppInfo.labelResource.moduleName);
181     want.SetParam(JUMP_DIALOG_TARGET_LABEL_ID, static_cast<long long>(targetAppInfo.labelId));
182     return true;
183 }
184 } // namespace AAFwk
185 } // namespace OHOS