1 /*
2 * Copyright (c) 2023-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 "dialog_session_manager.h"
17
18 #include <random>
19 #include "ability_manager_service.h"
20 #include "ability_util.h"
21 #include "hitrace_meter.h"
22 #include "int_wrapper.h"
23 #include "modal_system_ui_extension.h"
24 #include "query_erms_manager.h"
25 #ifdef SUPPORT_SCREEN
26 #include "scene_board_judgement.h"
27 #include "session_manager_lite.h"
28 #endif
29 #include "start_ability_utils.h"
30 #include "string_wrapper.h"
31 #include "want.h"
32
33 const std::string APP_LAUNCH_TRUSTLIST = "ohos.params.appLaunchTrustList";
34 namespace OHOS {
35 namespace AAFwk {
36 using OHOS::AppExecFwk::BundleInfo;
37 namespace {
38 constexpr const char* UIEXTENSION_MODAL_TYPE = "ability.want.params.modalType";
39 constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
40 constexpr const char* SUPPORT_CLOSE_ON_BLUR = "supportCloseOnBlur";
41 constexpr const char* DIALOG_SESSION_ID = "dialogSessionId";
42 constexpr const char* PICKER_ERMS_POLICY = "ability.params.picker.erms.policy";
43 }
44
GetInstance()45 DialogSessionManager &DialogSessionManager::GetInstance()
46 {
47 static DialogSessionManager instance;
48 return instance;
49 }
50
GenerateDialogSessionId()51 std::string DialogSessionManager::GenerateDialogSessionId()
52 {
53 auto timestamp = std::chrono::system_clock::now().time_since_epoch();
54 auto time = std::chrono::duration_cast<std::chrono::seconds>(timestamp).count();
55 std::random_device seed;
56 std::mt19937 rng(seed());
57 std::uniform_int_distribution<int> uni(0, INT_MAX);
58 int randomDigit = uni(rng);
59 std::string dialogSessionId = std::to_string(time) + "_" + std::to_string(randomDigit);
60
61 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
62 auto iter = dialogSessionInfoMap_.find(dialogSessionId);
63 while (iter != dialogSessionInfoMap_.end()) {
64 dialogSessionId += "_1";
65 iter = dialogSessionInfoMap_.find(dialogSessionId);
66 }
67 return dialogSessionId;
68 }
69
SetStartupSessionInfo(const std::string & dialogSessionId,const AbilityRequest & abilityRequest)70 void DialogSessionManager::SetStartupSessionInfo(const std::string &dialogSessionId,
71 const AbilityRequest &abilityRequest)
72 {
73 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
74 std::shared_ptr<StartupSessionInfo> startupSessionInfo = std::make_shared<StartupSessionInfo>();
75 startupSessionInfo->abilityRequest = abilityRequest;
76 startupSessionInfoMap_[dialogSessionId] = startupSessionInfo;
77 }
78
SetDialogSessionInfo(const std::string & dialogSessionId,sptr<DialogSessionInfo> & dilogSessionInfo,std::shared_ptr<DialogCallerInfo> & dialogCallerInfo)79 void DialogSessionManager::SetDialogSessionInfo(const std::string &dialogSessionId,
80 sptr<DialogSessionInfo> &dilogSessionInfo, std::shared_ptr<DialogCallerInfo> &dialogCallerInfo)
81 {
82 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
83 dialogSessionInfoMap_[dialogSessionId] = dilogSessionInfo;
84 dialogCallerInfoMap_[dialogSessionId] = dialogCallerInfo;
85 }
86
SetQueryERMSInfo(const std::string & dialogSessionId,const AbilityRequest & abilityRequest)87 void DialogSessionManager::SetQueryERMSInfo(const std::string &dialogSessionId,
88 const AbilityRequest &abilityRequest)
89 {
90 if (!abilityRequest.isQueryERMS) {
91 return;
92 }
93 std::lock_guard<ffrt::mutex> guard(queryERMSInfoLock_);
94 queryERMSInfoMap_.insert(std::pair<std::string, QueryERMSInfo>(dialogSessionId,
95 {
96 abilityRequest.callerTokenRecordId,
97 abilityRequest.appId,
98 abilityRequest.startTime,
99 abilityRequest.isEmbeddedAllowed
100 }));
101 }
102
NotifyQueryERMSFinished(const std::string & dialogSessionId,bool isAllowed)103 bool DialogSessionManager::NotifyQueryERMSFinished(const std::string &dialogSessionId, bool isAllowed)
104 {
105 QueryERMSInfo info;
106 {
107 std::lock_guard<ffrt::mutex> guard(queryERMSInfoLock_);
108 auto it = queryERMSInfoMap_.find(dialogSessionId);
109 if (it == queryERMSInfoMap_.end()) {
110 return false;
111 }
112 TAG_LOGI(AAFwkTag::DIALOG, "found,id=%{public}s", dialogSessionId.c_str());
113 info = it->second;
114 queryERMSInfoMap_.erase(dialogSessionId);
115 }
116 AtomicServiceStartupRule rule = { isAllowed, info.isEmbeddedAllowed };
117 QueryERMSManager::GetInstance().OnQueryFinished(info.recordId, info.appId, info.startTime, rule, ERR_OK);
118 return true;
119 }
120
GetDialogSessionInfo(const std::string & dialogSessionId) const121 sptr<DialogSessionInfo> DialogSessionManager::GetDialogSessionInfo(const std::string &dialogSessionId) const
122 {
123 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
124 auto it = dialogSessionInfoMap_.find(dialogSessionId);
125 if (it != dialogSessionInfoMap_.end()) {
126 return it->second;
127 }
128 TAG_LOGI(AAFwkTag::DIALOG, "not find");
129 return nullptr;
130 }
131
GetDialogCallerInfo(const std::string & dialogSessionId) const132 std::shared_ptr<DialogCallerInfo> DialogSessionManager::GetDialogCallerInfo(const std::string &dialogSessionId) const
133 {
134 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
135 auto it = dialogCallerInfoMap_.find(dialogSessionId);
136 if (it != dialogCallerInfoMap_.end()) {
137 return it->second;
138 }
139 TAG_LOGI(AAFwkTag::DIALOG, "not find");
140 return nullptr;
141 }
142
GetStartupSessionInfo(const std::string & dialogSessionId) const143 std::shared_ptr<StartupSessionInfo> DialogSessionManager::GetStartupSessionInfo(
144 const std::string &dialogSessionId) const
145 {
146 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
147 auto it = startupSessionInfoMap_.find(dialogSessionId);
148 if (it != startupSessionInfoMap_.end()) {
149 return it->second;
150 }
151 TAG_LOGI(AAFwkTag::DIALOG, "not find");
152 return nullptr;
153 }
154
ClearDialogContext(const std::string & dialogSessionId)155 void DialogSessionManager::ClearDialogContext(const std::string &dialogSessionId)
156 {
157 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
158 dialogSessionInfoMap_.erase(dialogSessionId);
159 dialogCallerInfoMap_.erase(dialogSessionId);
160 startupSessionInfoMap_.erase(dialogSessionId);
161 return;
162 }
163
ClearAllDialogContexts()164 void DialogSessionManager::ClearAllDialogContexts()
165 {
166 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
167 dialogSessionInfoMap_.clear();
168 dialogCallerInfoMap_.clear();
169 startupSessionInfoMap_.clear();
170 }
171
GenerateCallerAbilityInfo(AbilityRequest & abilityRequest,DialogAbilityInfo & callerAbilityInfo)172 void DialogSessionManager::GenerateCallerAbilityInfo(AbilityRequest &abilityRequest,
173 DialogAbilityInfo &callerAbilityInfo)
174 {
175 sptr<IRemoteObject> callerToken = abilityRequest.callerToken;
176 if (callerToken != nullptr) {
177 auto callerRecord = Token::GetAbilityRecordByToken(callerToken);
178 CHECK_POINTER(callerRecord);
179 callerAbilityInfo.bundleName = callerRecord->GetAbilityInfo().bundleName;
180 callerAbilityInfo.moduleName = callerRecord->GetAbilityInfo().moduleName;
181 callerAbilityInfo.abilityName = callerRecord->GetAbilityInfo().name;
182 callerAbilityInfo.abilityIconId = callerRecord->GetAbilityInfo().iconId;
183 callerAbilityInfo.abilityLabelId = callerRecord->GetAbilityInfo().labelId;
184 callerAbilityInfo.bundleIconId = callerRecord->GetApplicationInfo().iconId;
185 callerAbilityInfo.bundleLabelId = callerRecord->GetApplicationInfo().labelId;
186 callerAbilityInfo.visible = callerRecord->GetAbilityInfo().visible;
187 callerAbilityInfo.appIndex = callerRecord->GetApplicationInfo().appIndex;
188 callerAbilityInfo.multiAppMode = callerRecord->GetApplicationInfo().multiAppMode;
189 }
190 }
191
GenerateSelectorTargetAbilityInfos(std::vector<DialogAppInfo> & dialogAppInfos,std::vector<DialogAbilityInfo> & targetAbilityInfos)192 void DialogSessionManager::GenerateSelectorTargetAbilityInfos(std::vector<DialogAppInfo> &dialogAppInfos,
193 std::vector<DialogAbilityInfo> &targetAbilityInfos)
194 {
195 for (auto &dialogAppInfo : dialogAppInfos) {
196 DialogAbilityInfo targetDialogAbilityInfo;
197 targetDialogAbilityInfo.bundleName = dialogAppInfo.bundleName;
198 targetDialogAbilityInfo.moduleName = dialogAppInfo.moduleName;
199 targetDialogAbilityInfo.abilityName = dialogAppInfo.abilityName;
200 targetDialogAbilityInfo.abilityIconId = dialogAppInfo.abilityIconId;
201 targetDialogAbilityInfo.abilityLabelId = dialogAppInfo.abilityLabelId;
202 targetDialogAbilityInfo.bundleIconId = dialogAppInfo.bundleIconId;
203 targetDialogAbilityInfo.bundleLabelId = dialogAppInfo.bundleLabelId;
204 targetDialogAbilityInfo.visible = dialogAppInfo.visible;
205 targetDialogAbilityInfo.appIndex = dialogAppInfo.appIndex;
206 targetDialogAbilityInfo.multiAppMode = dialogAppInfo.multiAppMode;
207 targetAbilityInfos.emplace_back(targetDialogAbilityInfo);
208 }
209 }
210
GenerateJumpTargetAbilityInfos(AbilityRequest & abilityRequest,std::vector<DialogAbilityInfo> & targetAbilityInfos)211 void DialogSessionManager::GenerateJumpTargetAbilityInfos(AbilityRequest &abilityRequest,
212 std::vector<DialogAbilityInfo> &targetAbilityInfos)
213 {
214 DialogAbilityInfo targetDialogAbilityInfo;
215 targetDialogAbilityInfo.bundleName = abilityRequest.abilityInfo.bundleName;
216 targetDialogAbilityInfo.moduleName = abilityRequest.abilityInfo.moduleName;
217 targetDialogAbilityInfo.abilityName = abilityRequest.abilityInfo.name;
218 targetDialogAbilityInfo.abilityIconId = abilityRequest.abilityInfo.iconId;
219 targetDialogAbilityInfo.abilityLabelId = abilityRequest.abilityInfo.labelId;
220 targetDialogAbilityInfo.bundleIconId = abilityRequest.abilityInfo.applicationInfo.iconId;
221 targetDialogAbilityInfo.bundleLabelId = abilityRequest.abilityInfo.applicationInfo.labelId;
222 targetDialogAbilityInfo.visible = abilityRequest.abilityInfo.visible;
223 targetDialogAbilityInfo.appIndex = abilityRequest.abilityInfo.applicationInfo.appIndex;
224 targetDialogAbilityInfo.multiAppMode = abilityRequest.abilityInfo.applicationInfo.multiAppMode;
225 targetAbilityInfos.emplace_back(targetDialogAbilityInfo);
226 }
227
GenerateDialogCallerInfo(AbilityRequest & abilityRequest,int32_t userId,std::shared_ptr<DialogCallerInfo> dialogCallerInfo,SelectorType type,bool needGrantUriPermission)228 void DialogSessionManager::GenerateDialogCallerInfo(AbilityRequest &abilityRequest, int32_t userId,
229 std::shared_ptr<DialogCallerInfo> dialogCallerInfo, SelectorType type, bool needGrantUriPermission)
230 {
231 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
232 CHECK_POINTER(dialogCallerInfo);
233 dialogCallerInfo->type = type;
234 dialogCallerInfo->callerToken = abilityRequest.callerToken;
235 dialogCallerInfo->requestCode = abilityRequest.requestCode;
236 dialogCallerInfo->targetWant = abilityRequest.want;
237 dialogCallerInfo->userId = userId;
238 dialogCallerInfo->needGrantUriPermission = needGrantUriPermission;
239 }
240
NotifyAbilityRequestFailure(const std::string & dialogSessionId,const Want & want)241 void DialogSessionManager::NotifyAbilityRequestFailure(const std::string &dialogSessionId, const Want &want)
242 {
243 auto callerInfo = GetDialogCallerInfo(dialogSessionId);
244 CHECK_POINTER(callerInfo);
245 auto requestId = callerInfo->targetWant.GetStringParam(KEY_REQUEST_ID);
246 if (requestId.empty() || callerInfo->callerToken == nullptr) {
247 TAG_LOGD(AAFwkTag::ABILITYMGR, "no need to handle ability request");
248 return;
249 }
250 auto abilityRecord = Token::GetAbilityRecordByToken(callerInfo->callerToken);
251 CHECK_POINTER(abilityRecord);
252 TAG_LOGI(AAFwkTag::ABILITYMGR, "handling ability request failure, requestId=%{public}s", requestId.c_str());
253 std::string message = "User refused redirection";
254 if (callerInfo->type == SelectorType::IMPLICIT_START_SELECTOR) {
255 message = "User closed the implicit startup picker";
256 } else if (callerInfo->type == SelectorType::APP_CLONE_SELECTOR) {
257 message = "User closed the app clone picker";
258 } else if (callerInfo->type == SelectorType::INTERCEPTOR_SELECTOR) {
259 message = "User closed the interceptor picker";
260 }
261 abilityRecord->NotifyAbilityRequestFailure(requestId, want.GetElement(), message);
262 }
263
SendDialogResult(const Want & want,const std::string & dialogSessionId,bool isAllowed)264 int DialogSessionManager::SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed)
265 {
266 if (NotifyQueryERMSFinished(dialogSessionId, isAllowed)) {
267 TAG_LOGI(AAFwkTag::ABILITYMGR, "query ERMS finished");
268 ClearDialogContext(dialogSessionId);
269 return ERR_OK;
270 }
271 if (!isAllowed) {
272 TAG_LOGI(AAFwkTag::ABILITYMGR, "user refuse to jump");
273 NotifyAbilityRequestFailure(dialogSessionId, want);
274 ClearDialogContext(dialogSessionId);
275 return ERR_OK;
276 }
277 std::shared_ptr<StartupSessionInfo> startupSessionInfo = GetStartupSessionInfo(dialogSessionId);
278 if (startupSessionInfo != nullptr) {
279 return NotifySCBToRecoveryAfterInterception(dialogSessionId, startupSessionInfo->abilityRequest);
280 }
281 std::shared_ptr<DialogCallerInfo> dialogCallerInfo = GetDialogCallerInfo(dialogSessionId);
282 if (dialogCallerInfo == nullptr) {
283 TAG_LOGE(AAFwkTag::ABILITYMGR, "dialogCallerInfo null");
284 ClearDialogContext(dialogSessionId);
285 return ERR_INVALID_VALUE;
286 }
287 auto targetWant = dialogCallerInfo->targetWant;
288 if (dialogCallerInfo->type != SelectorType::INTERCEPTOR_SELECTOR) {
289 targetWant.SetElement(want.GetElement());
290 }
291 targetWant.SetParam("isSelector", dialogCallerInfo->type != SelectorType::WITHOUT_SELECTOR);
292 targetWant.SetParam(DIALOG_SESSION_ID, dialogSessionId);
293 if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) {
294 int32_t appIndex = want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
295 targetWant.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, appIndex);
296 }
297 targetWant.RemoveParam(PICKER_ERMS_POLICY);
298 if (want.HasParameter(PICKER_ERMS_POLICY)) {
299 targetWant.SetParam(PICKER_ERMS_POLICY, want.GetParams().GetIntParam(PICKER_ERMS_POLICY, 1));
300 }
301 if (!targetWant.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) {
302 targetWant.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
303 }
304 sptr<IRemoteObject> callerToken = dialogCallerInfo->callerToken;
305 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
306 CHECK_POINTER_AND_RETURN(abilityMgr, INNER_ERR);
307 int ret = abilityMgr->StartAbilityAsCallerDetails(targetWant, callerToken, callerToken, dialogCallerInfo->userId,
308 dialogCallerInfo->requestCode, false);
309 if (ret == ERR_OK) {
310 ClearDialogContext(dialogSessionId);
311 abilityMgr->RemoveSelectorIdentity(dialogCallerInfo->targetWant.GetIntParam(Want::PARAM_RESV_CALLER_TOKEN, 0));
312 }
313 return ret;
314 }
315
NotifySCBToRecoveryAfterInterception(const std::string & dialogSessionId,const AbilityRequest & abilityRequest)316 int32_t DialogSessionManager::NotifySCBToRecoveryAfterInterception(const std::string &dialogSessionId,
317 const AbilityRequest &abilityRequest)
318 {
319 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
320 if (!abilityMgr) {
321 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityMgr is nullptr.");
322 return INNER_ERR;
323 }
324 int ret = IN_PROCESS_CALL(abilityMgr->NotifySCBToRecoveryAfterInterception(abilityRequest));
325 if (ret == ERR_OK) {
326 ClearDialogContext(dialogSessionId);
327 }
328 return ret;
329 }
330
GenerateDialogSessionRecordCommon(AbilityRequest & abilityRequest,int32_t userId,const AAFwk::WantParams & parameters,std::vector<DialogAppInfo> & dialogAppInfos,SelectorType type,bool needGrantUriPermission)331 std::string DialogSessionManager::GenerateDialogSessionRecordCommon(AbilityRequest &abilityRequest, int32_t userId,
332 const AAFwk::WantParams ¶meters, std::vector<DialogAppInfo> &dialogAppInfos, SelectorType type,
333 bool needGrantUriPermission)
334 {
335 auto dialogSessionInfo = sptr<DialogSessionInfo>::MakeSptr();
336 CHECK_POINTER_AND_RETURN(dialogSessionInfo, "");
337
338 GenerateCallerAbilityInfo(abilityRequest, dialogSessionInfo->callerAbilityInfo);
339
340 if (type != SelectorType::WITHOUT_SELECTOR) {
341 GenerateSelectorTargetAbilityInfos(dialogAppInfos, dialogSessionInfo->targetAbilityInfos);
342 } else {
343 GenerateJumpTargetAbilityInfos(abilityRequest, dialogSessionInfo->targetAbilityInfos);
344 }
345
346 dialogSessionInfo->parameters = parameters;
347
348 std::shared_ptr<DialogCallerInfo> dialogCallerInfo = std::make_shared<DialogCallerInfo>();
349 GenerateDialogCallerInfo(abilityRequest, userId, dialogCallerInfo, type, needGrantUriPermission);
350
351 std::string dialogSessionId = GenerateDialogSessionId();
352 SetDialogSessionInfo(dialogSessionId, dialogSessionInfo, dialogCallerInfo);
353 SetQueryERMSInfo(dialogSessionId, abilityRequest);
354
355 return dialogSessionId;
356 }
357
CreateJumpModalDialog(AbilityRequest & abilityRequest,int32_t userId,const Want & replaceWant)358 int DialogSessionManager::CreateJumpModalDialog(AbilityRequest &abilityRequest, int32_t userId,
359 const Want &replaceWant)
360 {
361 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
362
363 AAFwk::WantParams parameters;
364
365 parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType()));
366 parameters.SetParam("userId", AAFwk::Integer::Box(userId));
367
368 std::vector<DialogAppInfo> dialogAppInfos;
369 std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, parameters,
370 dialogAppInfos, SelectorType::WITHOUT_SELECTOR);
371 if (dialogSessionId == "") {
372 TAG_LOGE(AAFwkTag::ABILITYMGR, "generation failed");
373 return ERR_INVALID_VALUE;
374 }
375
376 return CreateModalDialogCommon(replaceWant, abilityRequest.callerToken, dialogSessionId);
377 }
378
CreateImplicitSelectorModalDialog(AbilityRequest & abilityRequest,const Want & want,int32_t userId,std::vector<DialogAppInfo> & dialogAppInfos,bool needGrantUriPermission)379 int DialogSessionManager::CreateImplicitSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want,
380 int32_t userId, std::vector<DialogAppInfo> &dialogAppInfos, bool needGrantUriPermission)
381 {
382 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
383
384 AAFwk::Want sessionWant;
385
386 sessionWant.SetParam("deviceType", OHOS::system::GetDeviceType());
387 sessionWant.SetParam("userId", userId);
388 sessionWant.SetParam("action", abilityRequest.want.GetAction());
389 sessionWant.SetParam("wantType", abilityRequest.want.GetType());
390 sessionWant.SetParam("uri", abilityRequest.want.GetUriString());
391 sessionWant.SetParam("entities", abilityRequest.want.GetEntities());
392 sessionWant.SetParam("appselector.selectorType", static_cast<int>(SelectorType::IMPLICIT_START_SELECTOR));
393 bool showCaller = abilityRequest.want.GetBoolParam("showCaller", false);
394 sessionWant.SetParam("showCaller", showCaller);
395 sessionWant.SetParam("ohos.ability.params.showDefaultPicker",
396 abilityRequest.want.GetBoolParam("ohos.ability.params.showDefaultPicker", false));
397 if (abilityRequest.want.HasParameter(APP_LAUNCH_TRUSTLIST)) {
398 sessionWant.SetParam(APP_LAUNCH_TRUSTLIST,
399 abilityRequest.want.GetStringArrayParam(APP_LAUNCH_TRUSTLIST));
400 TAG_LOGD(AAFwkTag::ABILITYMGR, "ImplicitSelector get trustlist %{public}zu",
401 sessionWant.GetStringArrayParam(APP_LAUNCH_TRUSTLIST).size());
402 std::vector<std::string> receiveList = sessionWant.GetStringArrayParam(APP_LAUNCH_TRUSTLIST);
403 for (const std::string& str : receiveList) {
404 TAG_LOGD(AAFwkTag::ABILITYMGR, "in trustlist: %{public}s", str.c_str());
405 }
406 }
407
408 std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, sessionWant.GetParams(),
409 dialogAppInfos, SelectorType::IMPLICIT_START_SELECTOR, needGrantUriPermission);
410 if (dialogSessionId == "") {
411 TAG_LOGE(AAFwkTag::ABILITYMGR, "generation failed");
412 return ERR_INVALID_VALUE;
413 }
414
415 return CreateModalDialogCommon(want, abilityRequest.callerToken, dialogSessionId);
416 }
417
CreateCloneSelectorModalDialog(AbilityRequest & abilityRequest,const Want & want,int32_t userId,std::vector<DialogAppInfo> & dialogAppInfos,const std::string & replaceWant)418 int DialogSessionManager::CreateCloneSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want,
419 int32_t userId, std::vector<DialogAppInfo> &dialogAppInfos, const std::string &replaceWant)
420 {
421 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
422 AAFwk::WantParams parameters;
423
424 parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType()));
425 parameters.SetParam("userId", AAFwk::Integer::Box(userId));
426 parameters.SetParam("appselector.selectorType",
427 AAFwk::Integer::Box(static_cast<int>(SelectorType::APP_CLONE_SELECTOR)));
428 if (replaceWant != "") {
429 parameters.SetParam("ecological.replaceWant", AAFwk::String::Box(replaceWant));
430 }
431
432 std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, parameters,
433 dialogAppInfos, SelectorType::APP_CLONE_SELECTOR);
434 if (dialogSessionId == "") {
435 TAG_LOGE(AAFwkTag::ABILITYMGR, "generation failed");
436 return ERR_INVALID_VALUE;
437 }
438
439 return CreateModalDialogCommon(want, abilityRequest.callerToken, dialogSessionId);
440 }
441
CreateModalDialogCommon(const Want & replaceWant,sptr<IRemoteObject> callerToken,const std::string & dialogSessionId)442 int DialogSessionManager::CreateModalDialogCommon(const Want &replaceWant, sptr<IRemoteObject> callerToken,
443 const std::string &dialogSessionId)
444 {
445 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
446 (const_cast<Want &>(replaceWant)).SetParam(DIALOG_SESSION_ID, dialogSessionId);
447 auto connection = std::make_shared<OHOS::Rosen::ModalSystemUiExtension>();
448 if (callerToken == nullptr) {
449 TAG_LOGD(AAFwkTag::ABILITYMGR, "create modal ui extension for system");
450 (const_cast<Want &>(replaceWant)).SetParam(UIEXTENSION_MODAL_TYPE, 1);
451 (const_cast<Want &>(replaceWant)).SetParam(SUPPORT_CLOSE_ON_BLUR, true);
452 return IN_PROCESS_CALL(connection->CreateModalUIExtension(replaceWant)) ? ERR_OK : INNER_ERR;
453 }
454 auto callerRecord = Token::GetAbilityRecordByToken(callerToken);
455 if (!callerRecord) {
456 TAG_LOGE(AAFwkTag::ABILITYMGR, "callerRecord null");
457 return ERR_INVALID_VALUE;
458 }
459
460 sptr<IRemoteObject> token;
461 bool isParent = false;
462 int32_t ret = ERR_INVALID_VALUE;
463 #ifdef SUPPORT_SCREEN
464 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
465 auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy();
466 if (sceneSessionManager == nullptr) {
467 TAG_LOGE(AAFwkTag::ABILITYMGR, "sceneSessionManager null");
468 return ERR_INVALID_VALUE;
469 }
470 ret = static_cast<int32_t>(sceneSessionManager->IsFocusWindowParent(callerToken, isParent));
471 TAG_LOGD(AAFwkTag::ABILITYMGR, "isParent = %{pubilc}d, ret = %{pubilc}d", isParent, ret);
472 } else {
473 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
474 if (!abilityMgr) {
475 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityMgr null");
476 return INNER_ERR;
477 }
478 ret = IN_PROCESS_CALL(abilityMgr->GetTopAbility(token));
479 }
480 #endif
481
482 if (ret == ERR_OK && callerRecord->GetAbilityInfo().type == AppExecFwk::AbilityType::PAGE &&
483 (isParent || token == callerToken)) {
484 TAG_LOGD(AAFwkTag::ABILITYMGR, "create modal ui extension for application");
485 return callerRecord->CreateModalUIExtension(replaceWant);
486 }
487
488 TAG_LOGD(AAFwkTag::ABILITYMGR, "create modal ui extension for system");
489 (const_cast<Want &>(replaceWant)).SetParam(UIEXTENSION_MODAL_TYPE, 1);
490 (const_cast<Want &>(replaceWant)).SetParam(SUPPORT_CLOSE_ON_BLUR, true);
491 return IN_PROCESS_CALL(connection->CreateModalUIExtension(replaceWant)) ? ERR_OK : INNER_ERR;
492 }
493
HandleErmsResult(AbilityRequest & abilityRequest,int32_t userId,const Want & replaceWant)494 int DialogSessionManager::HandleErmsResult(AbilityRequest &abilityRequest, int32_t userId,
495 const Want &replaceWant)
496 {
497 std::string bundleName = abilityRequest.abilityInfo.bundleName;
498 if (StartAbilityUtils::ermsResultCode < ERMS_ISALLOW_RESULTCODE ||
499 !IsCreateCloneSelectorDialog(bundleName, userId)) {
500 TAG_LOGI(AAFwkTag::ABILITYMGR, "create jump modal dialog");
501 return CreateJumpModalDialog(abilityRequest, userId, replaceWant);
502 }
503 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
504 if (!abilityMgr) {
505 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityMgr null");
506 return INNER_ERR;
507 }
508 (const_cast<Want &>(replaceWant)).RemoveParam("ecological_experience_original_target");
509 return abilityMgr->CreateCloneSelectorDialog(abilityRequest, userId, replaceWant.ToString());
510 }
511
HandleErmsResultBySCB(AbilityRequest & abilityRequest,const Want & replaceWant)512 int32_t DialogSessionManager::HandleErmsResultBySCB(AbilityRequest &abilityRequest, const Want &replaceWant)
513 {
514 auto systemUIExtension = std::make_shared<OHOS::Rosen::ModalSystemUiExtension>();
515 (const_cast<Want &>(replaceWant)).SetParam(UIEXTENSION_MODAL_TYPE, 1);
516 (const_cast<Want &>(replaceWant)).SetParam(SUPPORT_CLOSE_ON_BLUR, true);
517 std::string dialogSessionId = GenerateDialogSessionId();
518 if (dialogSessionId == "") {
519 TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed");
520 return ERR_INVALID_VALUE;
521 }
522 SetStartupSessionInfo(dialogSessionId, abilityRequest);
523 (const_cast<Want &>(replaceWant)).SetParam(DIALOG_SESSION_ID, dialogSessionId);
524 return IN_PROCESS_CALL(systemUIExtension->CreateModalUIExtension(replaceWant)) ?
525 ERR_ECOLOGICAL_CONTROL_STATUS : INNER_ERR;
526 }
527
IsCreateCloneSelectorDialog(const std::string & bundleName,int32_t userId)528 bool DialogSessionManager::IsCreateCloneSelectorDialog(const std::string &bundleName, int32_t userId)
529 {
530 if (StartAbilityUtils::isWantWithAppCloneIndex) {
531 TAG_LOGI(AAFwkTag::ABILITYMGR, "no clone index");
532 StartAbilityUtils::isWantWithAppCloneIndex = false;
533 return false;
534 }
535 auto appIndexes = StartAbilityUtils::GetCloneAppIndexes(bundleName, userId);
536 if (appIndexes.empty()) {
537 TAG_LOGI(AAFwkTag::ABILITYMGR, "not create clone index");
538 return false;
539 }
540 return true;
541 }
542
UpdateExtensionWantWithDialogCallerInfo(AbilityRequest & abilityRequest,const sptr<IRemoteObject> & callerToken,bool isSCBCall)543 bool DialogSessionManager::UpdateExtensionWantWithDialogCallerInfo(AbilityRequest &abilityRequest,
544 const sptr<IRemoteObject> &callerToken, bool isSCBCall)
545 {
546 if (callerToken == nullptr) {
547 TAG_LOGW(AAFwkTag::ABILITYMGR, "callerToken null");
548 return false;
549 }
550 std::string dialogSessionId = abilityRequest.want.GetStringParam(DIALOG_SESSION_ID);
551 if (dialogSessionId.empty()) {
552 return false;
553 }
554 TAG_LOGI(AAFwkTag::ABILITYMGR, "dialogSessionId:%{public}s", dialogSessionId.c_str());
555 auto dialogCallerInfo = GetDialogCallerInfo(dialogSessionId);
556 if (dialogCallerInfo == nullptr) {
557 TAG_LOGW(AAFwkTag::ABILITYMGR, "dialogCallerInfo null");
558 return false;
559 }
560 if (!dialogCallerInfo->needGrantUriPermission) {
561 TAG_LOGI(AAFwkTag::ABILITYMGR, "no need grant uri permission");
562 return false;
563 }
564 TAG_LOGI(AAFwkTag::ABILITYMGR, "get dialog caller info");
565 auto dialogTargetWant = dialogCallerInfo->targetWant;
566 auto flag = dialogTargetWant.GetFlags();
567 if ((flag & (Want::FLAG_AUTH_READ_URI_PERMISSION | Want::FLAG_AUTH_WRITE_URI_PERMISSION)) == 0) {
568 TAG_LOGI(AAFwkTag::ABILITYMGR, "not grant flag");
569 return false;
570 }
571 if (!isSCBCall && (dialogCallerInfo->callerToken != callerToken)) {
572 TAG_LOGI(AAFwkTag::ABILITYMGR, "not scb call or callerToken invalid");
573 return false;
574 }
575 // only reserve grant uri flag
576 abilityRequest.want.SetFlags(dialogTargetWant.GetFlags());
577 abilityRequest.want.SetUri(dialogTargetWant.GetUri());
578 auto uriVec = dialogTargetWant.GetStringArrayParam(AbilityConfig::PARAMS_STREAM);
579 abilityRequest.want.SetParam(AbilityConfig::PARAMS_STREAM, uriVec);
580 if (!isSCBCall) {
581 TAG_LOGI(AAFwkTag::ABILITYMGR, "not scb call");
582 return true;
583 }
584 auto abilityRecord = Token::GetAbilityRecordByToken(dialogCallerInfo->callerToken);
585 if (abilityRecord) {
586 TAG_LOGI(AAFwkTag::ABILITYMGR, "set specifyTokenId");
587 abilityRequest.specifyTokenId = abilityRecord->GetApplicationInfo().accessTokenId;
588 return true;
589 }
590 return false;
591 }
592
OnlySetDialogCallerInfo(AbilityRequest & abilityRequest,int32_t userId,SelectorType type,const std::string & dialogSessionId,bool needGrantUriPermission)593 void DialogSessionManager::OnlySetDialogCallerInfo(AbilityRequest &abilityRequest, int32_t userId,
594 SelectorType type, const std::string &dialogSessionId, bool needGrantUriPermission)
595 {
596 std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
597 std::shared_ptr<DialogCallerInfo> dialogCallerInfo = std::make_shared<DialogCallerInfo>();
598 GenerateDialogCallerInfo(abilityRequest, userId, dialogCallerInfo, type, needGrantUriPermission);
599 dialogCallerInfoMap_[dialogSessionId] = dialogCallerInfo;
600 }
601 } // namespace AAFwk
602 } // namespace OHOS
603