• 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/ecological_rule_interceptor.h"
17 
18 #include "ability_record.h"
19 #include "ability_util.h"
20 #include "ecological_rule/ability_ecological_rule_mgr_service.h"
21 #include "hitrace_meter.h"
22 #include "parameters.h"
23 #include "start_ability_utils.h"
24 
25 namespace OHOS {
26 namespace AAFwk {
27 namespace {
28 constexpr const char* ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE =
29     "persist.sys.abilityms.support.ecologicalrulemgrservice";
30 constexpr const char* BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
31 constexpr const char* START_ABILITY_AS_CALLER_SKIP_ERMS = "ability.params.skipErms";
32 constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
33 }
DoProcess(AbilityInterceptorParam param)34 ErrCode EcologicalRuleInterceptor::DoProcess(AbilityInterceptorParam param)
35 {
36     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
37     if (param.isStartAsCaller && param.want.GetBoolParam(START_ABILITY_AS_CALLER_SKIP_ERMS, false)) {
38         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "start as caller, skip erms");
39         return ERR_OK;
40     }
41     if (StartAbilityUtils::skipErms) {
42         StartAbilityUtils::skipErms = false;
43         return ERR_OK;
44     }
45     if (param.want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME) ==
46         param.want.GetElement().GetBundleName()) {
47         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "same bundle");
48         return ERR_OK;
49     }
50     ErmsCallerInfo callerInfo;
51     ExperienceRule rule;
52     AAFwk::Want newWant = param.want;
53     newWant.RemoveAllFd();
54     InitErmsCallerInfo(newWant, param.abilityInfo, callerInfo, param.userId, param.callerToken);
55 
56     int ret = IN_PROCESS_CALL(AbilityEcologicalRuleMgrServiceClient::GetInstance()->QueryStartExperience(newWant,
57         callerInfo, rule));
58     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "isBackSkuExempt: %{public}d.", rule.isBackSkuExempt);
59     if (ret != ERR_OK) {
60         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule failed");
61         return ERR_OK;
62     }
63     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule success");
64     StartAbilityUtils::ermsResultCode = rule.resultCode;
65     StartAbilityUtils::ermsSupportBackToCallerFlag = rule.isBackSkuExempt;
66     if (rule.resultCode == ERMS_ISALLOW_RESULTCODE) {
67         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "allow ecological rule");
68         return ERR_OK;
69     }
70 
71     std::string supportErms = OHOS::system::GetParameter(ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE, "true");
72     if (supportErms == "false") {
73         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "erms between apps not supported");
74         return ERR_OK;
75     }
76 #ifdef SUPPORT_GRAPHICS
77     if (param.isWithUI && rule.replaceWant) {
78         (const_cast<Want &>(param.want)) = *rule.replaceWant;
79         (const_cast<Want &>(param.want)).SetParam("queryWantFromErms", true);
80     }
81 #endif
82     return ERR_ECOLOGICAL_CONTROL_STATUS;
83 }
84 
DoProcess(Want & want,int32_t userId)85 bool EcologicalRuleInterceptor::DoProcess(Want &want, int32_t userId)
86 {
87     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
88     if (want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME) == want.GetElement().GetBundleName()) {
89         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "same bundle");
90         return true;
91     }
92     std::string supportErms = OHOS::system::GetParameter(ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE, "true");
93     if (supportErms == "false") {
94         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "Erms between apps not supported");
95         return true;
96     }
97 
98     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
99     CHECK_POINTER_AND_RETURN(bundleMgrHelper, false);
100     Want launchWant;
101     auto errCode = IN_PROCESS_CALL(bundleMgrHelper->GetLaunchWantForBundle(want.GetBundle(), launchWant, userId));
102     if (errCode != ERR_OK) {
103         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "GetLaunchWantForBundle err: %{public}d", errCode);
104         return false;
105     }
106     want.SetElement(launchWant.GetElement());
107 
108     int32_t appIndex = 0;
109     StartAbilityUtils::startAbilityInfo = StartAbilityInfo::CreateStartAbilityInfo(want,
110         userId, appIndex);
111     if (StartAbilityUtils::startAbilityInfo->status != ERR_OK) {
112         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "Get targetApplicationInfo failed");
113         return false;
114     }
115 
116     ErmsCallerInfo callerInfo;
117     InitErmsCallerInfo(want, nullptr, callerInfo, userId);
118 
119     ExperienceRule rule;
120     auto ret = IN_PROCESS_CALL(AbilityEcologicalRuleMgrServiceClient::GetInstance()->QueryStartExperience(want,
121         callerInfo, rule));
122     if (ret != ERR_OK) {
123         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule failed");
124         return true;
125     }
126     return rule.resultCode == ERMS_ISALLOW_RESULTCODE;
127 }
128 
GetEcologicalTargetInfo(const Want & want,const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo,ErmsCallerInfo & callerInfo)129 void EcologicalRuleInterceptor::GetEcologicalTargetInfo(const Want &want,
130     const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo, ErmsCallerInfo &callerInfo)
131 {
132     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
133     callerInfo.targetLinkFeature = want.GetStringParam("send_to_erms_targetLinkFeature");
134     callerInfo.targetLinkType = want.GetIntParam("send_to_erms_targetLinkType", 0);
135     if (StartAbilityUtils::startAbilityInfo &&
136         StartAbilityUtils::startAbilityInfo->abilityInfo.bundleName == want.GetBundle() &&
137         StartAbilityUtils::startAbilityInfo->abilityInfo.name == want.GetElement().GetAbilityName()) {
138         AppExecFwk::AbilityInfo targetAbilityInfo = StartAbilityUtils::startAbilityInfo->abilityInfo;
139         callerInfo.targetAppDistType = targetAbilityInfo.applicationInfo.appDistributionType;
140         callerInfo.targetAppProvisionType = targetAbilityInfo.applicationInfo.appProvisionType;
141         callerInfo.targetAppType = GetAppTypeByBundleType(static_cast<int32_t>(
142             targetAbilityInfo.applicationInfo.bundleType));
143         callerInfo.targetAbilityType = targetAbilityInfo.type;
144         callerInfo.targetExtensionAbilityType = targetAbilityInfo.extensionAbilityType;
145     } else if (abilityInfo != nullptr) {
146         callerInfo.targetAppDistType = abilityInfo->applicationInfo.appDistributionType;
147         callerInfo.targetAppProvisionType = abilityInfo->applicationInfo.appProvisionType;
148         callerInfo.targetAppType = GetAppTypeByBundleType(static_cast<int32_t>(
149             abilityInfo->applicationInfo.bundleType));
150         callerInfo.targetAbilityType = abilityInfo->type;
151         callerInfo.targetExtensionAbilityType = abilityInfo->extensionAbilityType;
152     }
153 }
154 
GetEcologicalCallerInfo(const Want & want,ErmsCallerInfo & callerInfo,int32_t userId,const sptr<IRemoteObject> & callerToken)155 void EcologicalRuleInterceptor::GetEcologicalCallerInfo(const Want &want, ErmsCallerInfo &callerInfo, int32_t userId,
156     const sptr<IRemoteObject> &callerToken)
157 {
158     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
159 
160     AppExecFwk::ApplicationInfo callerAppInfo;
161     AppExecFwk::AbilityInfo callerAbilityInfo;
162     if (StartAbilityUtils::GetCallerAbilityInfo(callerToken, callerAbilityInfo)) {
163         callerAppInfo = callerAbilityInfo.applicationInfo;
164         callerInfo.callerAbilityType = callerAbilityInfo.type;
165         callerInfo.callerExtensionAbilityType = callerAbilityInfo.extensionAbilityType;
166     } else {
167         auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
168         if (bundleMgrHelper == nullptr) {
169             TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null bundleMgrHelper");
170             return;
171         }
172 
173         std::string callerBundleName;
174         ErrCode err = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerInfo.uid, callerBundleName));
175         if (err != ERR_OK) {
176             TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "Get callerBundleName failed,uid: %{public}d", callerInfo.uid);
177             return;
178         }
179         bool getCallerResult = IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(callerBundleName,
180             AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, callerAppInfo));
181         if (!getCallerResult) {
182             TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "Get callerAppInfo failed");
183             return;
184         }
185     }
186 
187     callerInfo.callerAppProvisionType = callerAppInfo.appProvisionType;
188     if (callerAppInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE) {
189         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "atomic service caller type");
190         callerInfo.callerAppType = ErmsCallerInfo::TYPE_ATOM_SERVICE;
191     } else if (callerAppInfo.bundleType == AppExecFwk::BundleType::APP) {
192         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "app caller type");
193         callerInfo.callerAppType = ErmsCallerInfo::TYPE_HARMONY_APP;
194         if (callerInfo.packageName == "" && callerAppInfo.name == BUNDLE_NAME_SCENEBOARD) {
195             callerInfo.packageName = BUNDLE_NAME_SCENEBOARD;
196         }
197     } else if (callerAppInfo.bundleType == AppExecFwk::BundleType::APP_SERVICE_FWK) {
198         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "app service caller type");
199         callerInfo.callerAppType = ErmsCallerInfo::TYPE_APP_SERVICE;
200     }
201 }
202 
InitErmsCallerInfo(const Want & want,const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo,ErmsCallerInfo & callerInfo,int32_t userId,const sptr<IRemoteObject> & callerToken)203 void EcologicalRuleInterceptor::InitErmsCallerInfo(const Want &want,
204     const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo,
205     ErmsCallerInfo &callerInfo, int32_t userId, const sptr<IRemoteObject> &callerToken)
206 {
207     if (callerToken != nullptr) {
208         auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
209         if (abilityRecord && !abilityRecord->GetAbilityInfo().isStageBasedModel) {
210             TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "FA callerModelType");
211             callerInfo.callerModelType = ErmsCallerInfo::MODEL_FA;
212         }
213     }
214     callerInfo.packageName = want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME);
215     callerInfo.uid = want.GetIntParam(Want::PARAM_RESV_CALLER_UID, IPCSkeleton::GetCallingUid());
216     callerInfo.pid = want.GetIntParam(Want::PARAM_RESV_CALLER_PID, IPCSkeleton::GetCallingPid());
217     callerInfo.embedded = want.GetIntParam("send_to_erms_embedded", 0);
218     callerInfo.userId = userId;
219 
220     GetEcologicalTargetInfo(want, abilityInfo, callerInfo);
221     GetEcologicalCallerInfo(want, callerInfo, userId, callerToken);
222     TAG_LOGI(AAFwkTag::ECOLOGICAL_RULE, "ERMS's %{public}s", callerInfo.ToString().c_str());
223 }
224 
GetAppTypeByBundleType(int32_t bundleType)225 int32_t EcologicalRuleInterceptor::GetAppTypeByBundleType(int32_t bundleType)
226 {
227     if (bundleType == static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE)) {
228         return ErmsCallerInfo::TYPE_ATOM_SERVICE;
229     }
230     if (bundleType == static_cast<int32_t>(AppExecFwk::BundleType::APP)) {
231         return ErmsCallerInfo::TYPE_HARMONY_APP;
232     }
233     if (bundleType == static_cast<int32_t>(AppExecFwk::BundleType::APP_SERVICE_FWK)) {
234         return ErmsCallerInfo::TYPE_APP_SERVICE;
235     }
236     return ErmsCallerInfo::TYPE_INVALID;
237 }
238 } // namespace AAFwk
239 } // namespace OHOS