• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "ability_interceptor.h"
17 
18 #include <chrono>
19 
20 #include "ability_info.h"
21 #include "ability_manager_errors.h"
22 #include "ability_record.h"
23 #include "accesstoken_kit.h"
24 #include "app_jump_control_rule.h"
25 #include "app_running_control_rule_result.h"
26 #include "bundle_constants.h"
27 #include "ecological_rule/ability_ecological_rule_mgr_service.h"
28 #include "hilog_wrapper.h"
29 #include "hitrace_meter.h"
30 #include "iservice_registry.h"
31 #include "in_process_call_wrapper.h"
32 #include "ipc_skeleton.h"
33 #include "modal_system_ui_extension.h"
34 #include "parameters.h"
35 #include "permission_constants.h"
36 #include "permission_verification.h"
37 #include "system_dialog_scheduler.h"
38 #include "want.h"
39 #include "want_params_wrapper.h"
40 namespace OHOS {
41 namespace AAFwk {
42 
43 const std::string ACTION_MARKET_CROWDTEST = "ohos.want.action.marketCrowdTest";
44 const std::string ACTION_MARKET_DISPOSED = "ohos.want.action.marketDisposed";
45 const std::string PERMISSION_MANAGE_DISPOSED_APP_STATUS = "ohos.permission.MANAGE_DISPOSED_APP_STATUS";
46 const std::string JUMP_DIALOG_CALLER_BUNDLE_NAME = "interceptor_callerBundleName";
47 const std::string JUMP_DIALOG_CALLER_MODULE_NAME = "interceptor_callerModuleName";
48 const std::string JUMP_DIALOG_CALLER_LABEL_ID = "interceptor_callerLabelId";
49 const std::string JUMP_DIALOG_TARGET_MODULE_NAME = "interceptor_targetModuleName";
50 const std::string JUMP_DIALOG_TARGET_LABEL_ID = "interceptor_targetLabelId";
51 const std::string UNREGISTER_EVENT_TASK = "unregister event task";
52 const std::string UNREGISTER_TIMEOUT_OBSERVER_TASK = "unregister timeout observer task";
53 const std::string ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE = "persist.sys.abilityms.support.ecologicalrulemgrservice";
54 const std::string IS_FROM_PARENTCONTROL = "ohos.ability.isFromParentControl";
55 const std::string INTERCEPT_PARAMETERS = "intercept_parammeters";
56 const std::string INTERCEPT_BUNDLE_NAME = "intercept_bundleName";
57 const std::string INTERCEPT_ABILITY_NAME = "intercept_abilityName";
58 const std::string INTERCEPT_MODULE_NAME = "intercept_moduleName";
59 const std::string BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
60 constexpr int UNREGISTER_OBSERVER_MICRO_SECONDS = 5000;
61 #define RETURN_BY_ISEDM(object)                 \
62     if (object) {                               \
63         return ERR_EDM_APP_CONTROLLED;          \
64     }                                           \
65     return ERR_APP_CONTROLLED;
66 
DoProcess(const Want & want,int requestCode,int32_t userId,bool isForeground,const sptr<IRemoteObject> & callerToken)67 ErrCode CrowdTestInterceptor::DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground,
68     const sptr<IRemoteObject> &callerToken)
69 {
70     if (CheckCrowdtest(want, userId)) {
71         HILOG_ERROR("Crowdtest expired.");
72 #ifdef SUPPORT_GRAPHICS
73         if (isForeground) {
74             int ret = IN_PROCESS_CALL(AbilityUtil::StartAppgallery(requestCode, userId, ACTION_MARKET_CROWDTEST));
75             if (ret != ERR_OK) {
76                 HILOG_ERROR("Crowdtest implicit start appgallery failed.");
77                 return ret;
78             }
79         }
80 #endif
81         return ERR_CROWDTEST_EXPIRED;
82     }
83     return ERR_OK;
84 }
85 
CheckCrowdtest(const Want & want,int32_t userId)86 bool CrowdTestInterceptor::CheckCrowdtest(const Want &want, int32_t userId)
87 {
88     // get bms
89     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
90     if (bundleMgrHelper == nullptr) {
91         HILOG_ERROR("The bundleMgrHelper is nullptr.");
92         return false;
93     }
94 
95     // get crowdtest status and time
96     std::string bundleName = want.GetBundle();
97     AppExecFwk::ApplicationInfo callerAppInfo;
98     bool result = IN_PROCESS_CALL(
99         bundleMgrHelper->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
100             userId, callerAppInfo)
101     );
102     if (!result) {
103         HILOG_DEBUG("GetApplicaionInfo from bms failed.");
104         return false;
105     }
106 
107     auto appDistributionType = callerAppInfo.appDistributionType;
108     auto appCrowdtestDeadline = callerAppInfo.crowdtestDeadline;
109     int64_t now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::
110         system_clock::now().time_since_epoch()).count();
111     if (appDistributionType == AppExecFwk::Constants::APP_DISTRIBUTION_TYPE_CROWDTESTING &&
112         appCrowdtestDeadline < now) {
113         HILOG_INFO("The application is expired, expired time is %{public}s",
114             std::to_string(appCrowdtestDeadline).c_str());
115         return true;
116     }
117     return false;
118 }
119 
DoProcess(const Want & want,int requestCode,int32_t userId,bool isForeground,const sptr<IRemoteObject> & callerToken)120 ErrCode ControlInterceptor::DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground,
121     const sptr<IRemoteObject> &callerToken)
122 {
123     AppExecFwk::AppRunningControlRuleResult controlRule;
124     if (CheckControl(want, userId, controlRule)) {
125         HILOG_INFO("The target application is intercpted. %{public}s", controlRule.controlMessage.c_str());
126 #ifdef SUPPORT_GRAPHICS
127         if (!isForeground || controlRule.controlWant == nullptr) {
128             HILOG_ERROR("Can not start control want");
129             RETURN_BY_ISEDM(controlRule.isEdm);
130         }
131         if (controlRule.controlWant->GetBoolParam(IS_FROM_PARENTCONTROL, false)) {
132             auto controlWant = controlRule.controlWant;
133             auto controlParam = controlWant->GetParams();
134             sptr<AAFwk::IWantParams> interceptParam = WantParamWrapper::Box(want.GetParams());
135             if (interceptParam != nullptr) {
136                 controlParam.SetParam(INTERCEPT_PARAMETERS, interceptParam);
137             }
138             controlWant->SetParams(controlParam);
139             controlWant->SetParam(INTERCEPT_BUNDLE_NAME, want.GetElement().GetBundleName());
140             controlWant->SetParam(INTERCEPT_ABILITY_NAME, want.GetElement().GetAbilityName());
141             controlWant->SetParam(INTERCEPT_MODULE_NAME, want.GetElement().GetModuleName());
142             controlRule.controlWant = controlWant;
143         }
144         int ret = IN_PROCESS_CALL(AbilityManagerClient::GetInstance()->StartAbility(*controlRule.controlWant,
145             requestCode, userId));
146         if (ret != ERR_OK) {
147             HILOG_ERROR("Control implicit start appgallery failed.");
148             return ret;
149         }
150 #endif
151         RETURN_BY_ISEDM(controlRule.isEdm);
152     }
153     return ERR_OK;
154 }
155 
CheckControl(const Want & want,int32_t userId,AppExecFwk::AppRunningControlRuleResult & controlRule)156 bool ControlInterceptor::CheckControl(const Want &want, int32_t userId,
157     AppExecFwk::AppRunningControlRuleResult &controlRule)
158 {
159     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
160     // get bms
161     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
162     if (bundleMgrHelper == nullptr) {
163         HILOG_ERROR("The bundleMgrHelper is nullptr.");
164         return false;
165     }
166 
167     // get disposed status
168     std::string bundleName = want.GetBundle();
169     auto appControlMgr = bundleMgrHelper->GetAppControlProxy();
170     if (appControlMgr == nullptr) {
171         HILOG_ERROR("The appControlMgr is nullptr.");
172         return false;
173     }
174 
175     auto ret = IN_PROCESS_CALL(appControlMgr->GetAppRunningControlRule(bundleName, userId, controlRule));
176     if (ret != ERR_OK) {
177         HILOG_DEBUG("Get No AppRunningControlRule.");
178         return false;
179     }
180     return true;
181 }
182 
DoProcess(const Want & want,int requestCode,int32_t userId,bool isForeground,const sptr<IRemoteObject> & callerToken)183 ErrCode DisposedRuleInterceptor::DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground,
184     const sptr<IRemoteObject> &callerToken)
185 {
186     HILOG_DEBUG("Call");
187     AppExecFwk::DisposedRule disposedRule;
188     if (CheckControl(want, userId, disposedRule)) {
189         HILOG_INFO("The target ability is intercpted.");
190 #ifdef SUPPORT_GRAPHICS
191         if (!isForeground || disposedRule.want == nullptr
192             || disposedRule.disposedType == AppExecFwk::DisposedType::NON_BLOCK) {
193             HILOG_ERROR("Can not start disposed want");
194             RETURN_BY_ISEDM(disposedRule.isEdm);
195         }
196         if (disposedRule.want->GetBundle() == want.GetBundle()) {
197             HILOG_ERROR("Can not start disposed want with same bundleName");
198             RETURN_BY_ISEDM(disposedRule.isEdm);
199         }
200         if (disposedRule.componentType == AppExecFwk::ComponentType::UI_ABILITY) {
201             int ret = IN_PROCESS_CALL(AbilityManagerClient::GetInstance()->StartAbility(*disposedRule.want,
202                 requestCode, userId));
203             if (ret != ERR_OK) {
204                 HILOG_ERROR("DisposedRuleInterceptor start ability failed.");
205                 return ret;
206             }
207         }
208         if (disposedRule.componentType == AppExecFwk::ComponentType::UI_EXTENSION) {
209             int ret = CreateModalUIExtension(*disposedRule.want, callerToken);
210             if (ret != ERR_OK) {
211                 HILOG_ERROR("failed to start disposed UIExtension");
212                 return ret;
213             }
214         }
215 #endif
216         RETURN_BY_ISEDM(disposedRule.isEdm);
217     }
218     if (disposedRule.disposedType != AppExecFwk::DisposedType::NON_BLOCK) {
219         return ERR_OK;
220     }
221     return StartNonBlockRule(want, disposedRule);
222 }
223 
CheckControl(const Want & want,int32_t userId,AppExecFwk::DisposedRule & disposedRule)224 bool DisposedRuleInterceptor::CheckControl(const Want &want, int32_t userId,
225     AppExecFwk::DisposedRule &disposedRule)
226 {
227     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
228     // get bms
229     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
230     if (bundleMgrHelper == nullptr) {
231         HILOG_ERROR("The bundleMgrHelper is nullptr.");
232         return false;
233     }
234 
235     // get disposed status
236     std::string bundleName = want.GetBundle();
237     auto appControlMgr = bundleMgrHelper->GetAppControlProxy();
238     if (appControlMgr == nullptr) {
239         HILOG_ERROR("The appControlMgr is nullptr.");
240         return false;
241     }
242     std::vector<AppExecFwk::DisposedRule> disposedRuleList;
243 
244     auto ret = IN_PROCESS_CALL(appControlMgr->GetAbilityRunningControlRule(bundleName,
245         userId, disposedRuleList));
246     if (ret != ERR_OK || disposedRuleList.empty()) {
247         HILOG_DEBUG("Get No DisposedRule");
248         return false;
249     }
250 
251     for (auto &rule:disposedRuleList) {
252         if (CheckDisposedRule(want, rule)) {
253             disposedRule = rule;
254             return true;
255         }
256     }
257     int priority = -1;
258     for (auto &rule : disposedRuleList) {
259         if (rule.disposedType != AppExecFwk::DisposedType::NON_BLOCK) {
260             return false;
261         }
262         if (rule.priority > priority) {
263             priority = rule.priority;
264             disposedRule = rule;
265         }
266     }
267     return false;
268 }
269 
CheckDisposedRule(const Want & want,AppExecFwk::DisposedRule & disposedRule)270 bool DisposedRuleInterceptor::CheckDisposedRule(const Want &want, AppExecFwk::DisposedRule &disposedRule)
271 {
272     if (disposedRule.disposedType == AppExecFwk::DisposedType::NON_BLOCK) {
273         return false;
274     }
275     bool isAllowed = disposedRule.controlType == AppExecFwk::ControlType::ALLOWED_LIST;
276     if (disposedRule.disposedType == AppExecFwk::DisposedType::BLOCK_APPLICATION) {
277         return !isAllowed;
278     }
279 
280     std::string moduleName = want.GetElement().GetModuleName();
281     std::string abilityName = want.GetElement().GetAbilityName();
282 
283     for (auto elementName : disposedRule.elementList) {
284         if (moduleName == elementName.GetModuleName()
285             && abilityName == elementName.GetAbilityName()) {
286             return !isAllowed;
287         }
288     }
289     return isAllowed;
290 }
291 
StartNonBlockRule(const Want & want,AppExecFwk::DisposedRule & disposedRule)292 ErrCode DisposedRuleInterceptor::StartNonBlockRule(const Want &want, AppExecFwk::DisposedRule &disposedRule)
293 {
294     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
295     HILOG_INFO("not block");
296     if (disposedRule.want == nullptr) {
297         HILOG_ERROR("Can not start disposed app, want is nullptr");
298         return ERR_OK;
299     }
300     if (disposedRule.want->GetBundle() == want.GetBundle()) {
301         HILOG_ERROR("Can not start disposed app with same bundleName");
302         return ERR_OK;
303     }
304     std::string bundleName = want.GetBundle();
305     {
306         std::lock_guard<ffrt::mutex> guard(observerLock_);
307         if (disposedObserverMap_.find(bundleName) != disposedObserverMap_.end()) {
308             HILOG_DEBUG("start same disposed app, do not need to register again");
309             return ERR_OK;
310         }
311     }
312     auto disposedObserver = sptr<DisposedObserver>::MakeSptr(disposedRule, shared_from_this());
313     CHECK_POINTER_AND_RETURN(disposedObserver, ERR_INVALID_VALUE);
314     sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppMgr();
315     CHECK_POINTER_AND_RETURN(appManager, ERR_INVALID_VALUE);
316     std::vector<std::string> bundleNameList;
317     bundleNameList.push_back(bundleName);
318     int32_t ret = IN_PROCESS_CALL(appManager->RegisterApplicationStateObserver(disposedObserver, bundleNameList));
319     if (ret != 0) {
320         HILOG_ERROR("register to appmanager failed. err:%{public}d", ret);
321         disposedObserver = nullptr;
322         return ret;
323     }
324     {
325         std::lock_guard<ffrt::mutex> guard(observerLock_);
326         disposedObserverMap_.emplace(bundleName, disposedObserver);
327     }
328     auto unregisterTask = [appManager, bundleName, interceptor = shared_from_this()] () {
329         std::lock_guard<ffrt::mutex> guard{interceptor->observerLock_};
330         auto iter = interceptor->disposedObserverMap_.find(bundleName);
331         if (iter != interceptor->disposedObserverMap_.end()) {
332             HILOG_ERROR("start disposed app time out, need to unregister observer");
333             IN_PROCESS_CALL(appManager->UnregisterApplicationStateObserver(iter->second));
334             interceptor->disposedObserverMap_.erase(iter);
335         }
336     };
337     taskHandler_->SubmitTask(unregisterTask, UNREGISTER_TIMEOUT_OBSERVER_TASK, UNREGISTER_OBSERVER_MICRO_SECONDS);
338     return ERR_OK;
339 }
340 
GetAppMgr()341 sptr<OHOS::AppExecFwk::IAppMgr> DisposedRuleInterceptor::GetAppMgr()
342 {
343     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
344         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
345     if (!systemAbilityManager) {
346         HILOG_ERROR("get systemAbilityManager failed");
347         return nullptr;
348     }
349     OHOS::sptr<OHOS::IRemoteObject> object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
350     if (!object) {
351         HILOG_ERROR("get systemAbilityManager failed");
352         return nullptr;
353     }
354     sptr<OHOS::AppExecFwk::IAppMgr> appMgr = iface_cast<AppExecFwk::IAppMgr>(object);
355     if (!appMgr || !appMgr->AsObject()) {
356         return nullptr;
357     }
358     return appMgr;
359 }
360 
UnregisterObserver(const std::string & bundleName)361 void DisposedRuleInterceptor::UnregisterObserver(const std::string &bundleName)
362 {
363     HILOG_DEBUG("Call");
364     taskHandler_->CancelTask(UNREGISTER_TIMEOUT_OBSERVER_TASK);
365     auto unregisterTask = [bundleName, interceptor = shared_from_this()] () {
366         std::lock_guard<ffrt::mutex> guard{interceptor->observerLock_};
367         auto iter = interceptor->disposedObserverMap_.find(bundleName);
368         if (iter == interceptor->disposedObserverMap_.end()) {
369             HILOG_ERROR("Can not find observer");
370         } else {
371             auto disposedObserver = iter->second;
372             CHECK_POINTER(disposedObserver);
373             sptr<OHOS::AppExecFwk::IAppMgr> appManager = interceptor->GetAppMgr();
374             CHECK_POINTER(appManager);
375             IN_PROCESS_CALL(appManager->UnregisterApplicationStateObserver(disposedObserver));
376             interceptor->disposedObserverMap_.erase(iter);
377         }
378     };
379     taskHandler_->SubmitTask(unregisterTask, UNREGISTER_EVENT_TASK);
380 }
381 
CreateModalUIExtension(const Want & want,const sptr<IRemoteObject> & callerToken)382 ErrCode DisposedRuleInterceptor::CreateModalUIExtension(const Want &want, const sptr<IRemoteObject> &callerToken)
383 {
384     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
385     auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
386     if (abilityRecord == nullptr) {
387         auto systemUIExtension = std::make_shared<OHOS::Rosen::ModalSystemUiExtension>();
388         return systemUIExtension->CreateModalUIExtension(want);
389     } else {
390         return abilityRecord->CreateModalUIExtension(want);
391     }
392 }
393 
DoProcess(const Want & want,int requestCode,int32_t userId,bool isForeground,const sptr<IRemoteObject> & callerToken)394 ErrCode EcologicalRuleInterceptor::DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground,
395     const sptr<IRemoteObject> &callerToken)
396 {
397     if (want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME) ==
398         want.GetElement().GetBundleName()) {
399         HILOG_DEBUG("The same bundle, do not intercept.");
400         return ERR_OK;
401     }
402     ErmsCallerInfo callerInfo;
403     ExperienceRule rule;
404     if (callerToken != nullptr) {
405         auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
406         if (abilityRecord && !abilityRecord->GetAbilityInfo().isStageBasedModel) {
407             HILOG_DEBUG("callerModelType is FA.");
408             callerInfo.callerModelType = ErmsCallerInfo::MODEL_FA;
409         }
410     }
411     GetEcologicalCallerInfo(want, callerInfo, userId);
412     std::string supportErms = OHOS::system::GetParameter(ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE, "true");
413     if (supportErms == "false") {
414         HILOG_ERROR("Abilityms not support Erms between applications.");
415         return ERR_OK;
416     }
417 
418     int ret = IN_PROCESS_CALL(AbilityEcologicalRuleMgrServiceClient::GetInstance()->QueryStartExperience(want,
419         callerInfo, rule));
420     if (ret != ERR_OK) {
421         HILOG_DEBUG("check ecological rule failed, keep going.");
422         return ERR_OK;
423     }
424     HILOG_DEBUG("check ecological rule success");
425     if (rule.isAllow) {
426         HILOG_DEBUG("ecological rule is allow, keep going.");
427         return ERR_OK;
428     }
429 #ifdef SUPPORT_GRAPHICS
430     if (isForeground && rule.replaceWant) {
431         (const_cast<Want &>(want)) = *rule.replaceWant;
432         (const_cast<Want &>(want)).SetParam("queryWantFromErms", true);
433     }
434 #endif
435     return ERR_ECOLOGICAL_CONTROL_STATUS;
436 }
437 
GetEcologicalCallerInfo(const Want & want,ErmsCallerInfo & callerInfo,int32_t userId)438 void EcologicalRuleInterceptor::GetEcologicalCallerInfo(const Want &want, ErmsCallerInfo &callerInfo, int32_t userId)
439 {
440     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
441     callerInfo.packageName = want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME);
442     callerInfo.uid = want.GetIntParam(Want::PARAM_RESV_CALLER_UID, IPCSkeleton::GetCallingUid());
443     callerInfo.pid = want.GetIntParam(Want::PARAM_RESV_CALLER_PID, IPCSkeleton::GetCallingPid());
444     callerInfo.targetAppType = ErmsCallerInfo::TYPE_INVALID;
445     callerInfo.callerAppType = ErmsCallerInfo::TYPE_INVALID;
446 
447     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
448     if (bundleMgrHelper == nullptr) {
449         HILOG_ERROR("The bundleMgrHelper is nullptr.");
450         return;
451     }
452 
453     std::string targetBundleName = want.GetBundle();
454     AppExecFwk::ApplicationInfo targetAppInfo;
455     bool getTargetResult = IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(targetBundleName,
456         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, targetAppInfo));
457     if (!getTargetResult) {
458         HILOG_ERROR("Get targetAppInfo failed.");
459     } else if (targetAppInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE) {
460         HILOG_DEBUG("the target type  is atomic service");
461         callerInfo.targetAppType = ErmsCallerInfo::TYPE_ATOM_SERVICE;
462     } else if (targetAppInfo.bundleType == AppExecFwk::BundleType::APP) {
463         HILOG_DEBUG("the target type is app");
464         callerInfo.targetAppType = ErmsCallerInfo::TYPE_HARMONY_APP;
465     }
466 
467     std::string callerBundleName;
468     ErrCode err = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerInfo.uid, callerBundleName));
469     if (err != ERR_OK) {
470         HILOG_ERROR("Get callerBundleName failed,uid: %{public}d.", callerInfo.uid);
471         return;
472     }
473     AppExecFwk::ApplicationInfo callerAppInfo;
474     bool getCallerResult = IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(callerBundleName,
475         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, callerAppInfo));
476     if (!getCallerResult) {
477         HILOG_DEBUG("Get callerAppInfo failed.");
478     } else if (callerAppInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE) {
479         HILOG_DEBUG("the caller type  is atomic service");
480         callerInfo.callerAppType = ErmsCallerInfo::TYPE_ATOM_SERVICE;
481     } else if (callerAppInfo.bundleType == AppExecFwk::BundleType::APP) {
482         HILOG_DEBUG("the caller type is app");
483         callerInfo.callerAppType = ErmsCallerInfo::TYPE_HARMONY_APP;
484         if (callerInfo.packageName == "" && callerAppInfo.name == BUNDLE_NAME_SCENEBOARD) {
485             callerInfo.packageName = BUNDLE_NAME_SCENEBOARD;
486         }
487     }
488 }
489 
DoProcess(const Want & want,int requestCode,int32_t userId,bool isForeground,const sptr<IRemoteObject> & callerToken)490 ErrCode AbilityJumpInterceptor::DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground,
491     const sptr<IRemoteObject> &callerToken)
492 {
493     if (!isForeground) {
494         HILOG_INFO("This startup is not foreground, keep going.");
495         return ERR_OK;
496     }
497     bool isStartIncludeAtomicService = AbilityUtil::IsStartIncludeAtomicService(want, userId);
498     if (isStartIncludeAtomicService) {
499         HILOG_INFO("This startup contain atomic service, keep going.");
500         return ERR_OK;
501     }
502     // get bms
503     auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
504     if (bundleMgrHelper == nullptr) {
505         HILOG_ERROR("The bundleMgrHelper is nullptr.");
506         return ERR_OK;
507     }
508     AppExecFwk::AbilityInfo targetAbilityInfo;
509     IN_PROCESS_CALL_WITHOUT_RET(bundleMgrHelper->QueryAbilityInfo(want,
510         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, targetAbilityInfo));
511     if (targetAbilityInfo.type != AppExecFwk::AbilityType::PAGE) {
512         HILOG_INFO("Target is not page Ability, keep going, abilityType:%{public}d.", targetAbilityInfo.type);
513         return ERR_OK;
514     }
515     AppExecFwk::AppJumpControlRule controlRule;
516     if (CheckControl(bundleMgrHelper, want, userId, controlRule)) {
517 #ifdef SUPPORT_GRAPHICS
518         HILOG_INFO("app jump need to be intercepted, caller:%{public}s, target:%{public}s",
519             controlRule.callerPkg.c_str(), controlRule.targetPkg.c_str());
520         auto sysDialogScheduler = DelayedSingleton<SystemDialogScheduler>::GetInstance();
521         Want targetWant = want;
522         Want dialogWant = sysDialogScheduler->GetJumpInterceptorDialogWant(targetWant);
523         AbilityUtil::ParseJumpInterceptorWant(dialogWant, controlRule.callerPkg);
524         LoadAppLabelInfo(bundleMgrHelper, dialogWant, controlRule, userId);
525         int ret = IN_PROCESS_CALL(AbilityManagerClient::GetInstance()->StartAbility(dialogWant,
526             requestCode, userId));
527         if (ret != ERR_OK) {
528             HILOG_INFO("appInterceptor Dialog StartAbility error, ret:%{public}d", ret);
529             return ret;
530         }
531 #endif
532         return ERR_APP_JUMP_INTERCEPTOR_STATUS;
533     }
534     return ERR_OK;
535 }
536 
CheckControl(std::shared_ptr<AppExecFwk::BundleMgrHelper> & bundleMgrHelper,const Want & want,int32_t userId,AppExecFwk::AppJumpControlRule & controlRule)537 bool AbilityJumpInterceptor::CheckControl(std::shared_ptr<AppExecFwk::BundleMgrHelper> &bundleMgrHelper,
538     const Want &want, int32_t userId, AppExecFwk::AppJumpControlRule &controlRule)
539 {
540     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
541     int callerUid = IPCSkeleton::GetCallingUid();
542     std::string callerBundleName;
543     auto result = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerUid, callerBundleName));
544     std::string targetBundleName = want.GetBundle();
545     controlRule.callerPkg = callerBundleName;
546     controlRule.targetPkg = targetBundleName;
547     if (result != ERR_OK) {
548         HILOG_ERROR("GetBundleName from bms fail.");
549         return false;
550     }
551     if (controlRule.callerPkg.empty() || controlRule.targetPkg.empty()) {
552         HILOG_INFO("This startup is not explicitly, keep going.");
553         return false;
554     }
555     if (controlRule.callerPkg == controlRule.targetPkg) {
556         HILOG_INFO("Jump within the same app.");
557         return false;
558     }
559     if (CheckIfJumpExempt(bundleMgrHelper, controlRule, userId)) {
560         HILOG_INFO("Jump from or to system or exempt apps.");
561         return false;
562     }
563     // get disposed status
564     auto appControlMgr = bundleMgrHelper->GetAppControlProxy();
565     if (appControlMgr == nullptr) {
566         HILOG_ERROR("Get appControlMgr failed.");
567         return false;
568     }
569 
570     if (IN_PROCESS_CALL(appControlMgr->GetAppJumpControlRule(callerBundleName, targetBundleName,
571         userId, controlRule)) != ERR_OK) {
572         HILOG_INFO("No jump control rule found.");
573         return true;
574     }
575     HILOG_INFO("Get appJumpControlRule, jumpMode:%d.", controlRule.jumpMode);
576     return controlRule.jumpMode != AppExecFwk::AbilityJumpMode::DIRECT;
577 }
578 
CheckIfJumpExempt(std::shared_ptr<AppExecFwk::BundleMgrHelper> & bundleMgrHelper,AppExecFwk::AppJumpControlRule & controlRule,int32_t userId)579 bool AbilityJumpInterceptor::CheckIfJumpExempt(std::shared_ptr<AppExecFwk::BundleMgrHelper> &bundleMgrHelper,
580     AppExecFwk::AppJumpControlRule &controlRule, int32_t userId)
581 {
582     if (CheckIfExemptByBundleName(bundleMgrHelper, controlRule.callerPkg,
583         PermissionConstants::PERMISSION_EXEMPT_AS_CALLER, userId)) {
584         HILOG_INFO("Jump from exempt caller app, No need to intercept.");
585         return true;
586     }
587     if (CheckIfExemptByBundleName(bundleMgrHelper, controlRule.targetPkg,
588         PermissionConstants::PERMISSION_EXEMPT_AS_TARGET, userId)) {
589         HILOG_INFO("Jump to exempt target app, No need to intercept.");
590         return true;
591     }
592     HILOG_INFO("Third-party apps jump to third-party apps.");
593     return false;
594 }
595 
CheckIfExemptByBundleName(std::shared_ptr<AppExecFwk::BundleMgrHelper> & bundleMgrHelper,const std::string & bundleName,const std::string & permission,int32_t userId)596 bool AbilityJumpInterceptor::CheckIfExemptByBundleName(std::shared_ptr<AppExecFwk::BundleMgrHelper> &bundleMgrHelper,
597     const std::string &bundleName, const std::string &permission, int32_t userId)
598 {
599     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
600     AppExecFwk::ApplicationInfo appInfo;
601     if (!IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT,
602         userId, appInfo))) {
603         HILOG_ERROR("VerifyPermission failed to get application info.");
604         return false;
605     }
606     if (appInfo.isSystemApp) {
607         HILOG_INFO("Bundle:%{public}s is system app.", bundleName.c_str());
608         return true;
609     }
610     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(appInfo.accessTokenId, permission, false);
611     if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) {
612         HILOG_DEBUG("VerifyPermission %{public}d: PERMISSION_DENIED.", appInfo.accessTokenId);
613         return false;
614     }
615     HILOG_INFO("Bundle:%{public}s verify permission:%{public}s successed.", bundleName.c_str(), permission.c_str());
616     return true;
617 }
618 
LoadAppLabelInfo(std::shared_ptr<AppExecFwk::BundleMgrHelper> & bundleMgrHelper,Want & want,AppExecFwk::AppJumpControlRule & controlRule,int32_t userId)619 bool AbilityJumpInterceptor::LoadAppLabelInfo(std::shared_ptr<AppExecFwk::BundleMgrHelper> &bundleMgrHelper, Want &want,
620     AppExecFwk::AppJumpControlRule &controlRule, int32_t userId)
621 {
622     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
623     AppExecFwk::ApplicationInfo callerAppInfo;
624     IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(controlRule.callerPkg,
625         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, callerAppInfo));
626     AppExecFwk::ApplicationInfo targetAppInfo;
627     IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(controlRule.targetPkg,
628         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, targetAppInfo));
629     want.SetParam(JUMP_DIALOG_CALLER_BUNDLE_NAME, controlRule.callerPkg);
630     want.SetParam(JUMP_DIALOG_CALLER_MODULE_NAME, callerAppInfo.labelResource.moduleName);
631     want.SetParam(JUMP_DIALOG_CALLER_LABEL_ID, callerAppInfo.labelId);
632     want.SetParam(JUMP_DIALOG_TARGET_MODULE_NAME, targetAppInfo.labelResource.moduleName);
633     want.SetParam(JUMP_DIALOG_TARGET_LABEL_ID, targetAppInfo.labelId);
634     return true;
635 }
636 } // namespace AAFwk
637 } // namespace OHOS
638