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