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