1 /*
2 * Copyright (c) 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 "session_manager/include/scene_session_manager.h"
17
18 #include <regex>
19
20 #include <ability_context.h>
21 #include <ability_manager_client.h>
22 #include <application_context.h>
23 #include <bundlemgr/launcher_service.h>
24 #include <hisysevent.h>
25 #include <parameters.h>
26 #include <hitrace_meter.h>
27 #include "parameter.h"
28 #include "publish/scb_dump_subscriber.h"
29 #include <ui/rs_node.h>
30
31 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
32 #include <display_power_mgr_client.h>
33 #endif
34
35 #ifdef POWER_MANAGER_ENABLE
36 #include <power_mgr_client.h>
37 #endif
38
39 #ifdef RES_SCHED_ENABLE
40 #include "res_type.h"
41 #include "res_sched_client.h"
42 #endif
43 #include "scene_system_ability_listener.h"
44
45 #include "anr_manager.h"
46 #include "color_parser.h"
47 #include "common/include/session_permission.h"
48 #include "display_manager.h"
49 #include "scene_input_manager.h"
50 #include "session/host/include/main_session.h"
51 #include "session/host/include/scb_system_session.h"
52 #include "session/host/include/scene_persistent_storage.h"
53 #include "session/host/include/session_utils.h"
54 #include "session/host/include/sub_session.h"
55 #include "session_helper.h"
56 #include "window_helper.h"
57 #include "screen_session_manager/include/screen_session_manager_client.h"
58 #include "singleton_container.h"
59 #include "xcollie/watchdog.h"
60 #include "session_manager_agent_controller.h"
61 #include "distributed_client.h"
62 #include "softbus_bus_center.h"
63 #include "perform_reporter.h"
64 #include "anr_manager.h"
65 #include "dms_reporter.h"
66 #include "res_sched_client.h"
67 #include "anomaly_detection.h"
68 #include "session/host/include/ability_info_manager.h"
69
70 #ifdef MEMMGR_WINDOW_ENABLE
71 #include "mem_mgr_client.h"
72 #include "mem_mgr_window_info.h"
73 #endif
74
75 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
76 #include "sec_comp_enhance_kit.h"
77 #endif
78
79 #ifdef IMF_ENABLE
80 #include <input_method_controller.h>
81 #endif // IMF_ENABLE
82
83 namespace OHOS::Rosen {
84 namespace {
85 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
86 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
87 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
88 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
89 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
90 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
91 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
92 constexpr uint32_t MAX_BRIGHTNESS = 255;
93 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
94 constexpr int32_t SCALE_DIMENSION = 2;
95 constexpr int32_t TRANSLATE_DIMENSION = 2;
96 constexpr int32_t ROTAION_DIMENSION = 4;
97 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
98 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
99 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
100 const std::string EMPTY_DEVICE_ID = "";
101 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
102
103 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
104 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
105 constexpr int VALUE_MAX_WIDTH = 5;
106 constexpr int MAX_RESEND_TIMES = 6;
107 constexpr int ORIEN_MAX_WIDTH = 12;
108 constexpr int OFFSET_MAX_WIDTH = 8;
109 constexpr int SCALE_MAX_WIDTH = 8;
110 constexpr int PID_MAX_WIDTH = 8;
111 constexpr int PARENT_ID_MAX_WIDTH = 6;
112 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
113 constexpr int32_t CANCEL_POINTER_ID = 99999999;
114 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
115 const std::string ARG_DUMP_ALL = "-a";
116 const std::string ARG_DUMP_WINDOW = "-w";
117 const std::string ARG_DUMP_SCREEN = "-s";
118 const std::string ARG_DUMP_DISPLAY = "-d";
119 const std::string ARG_DUMP_PIPLINE = "-p";
120 const std::string ARG_DUMP_SCB = "-b";
121 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
122 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
123 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
124 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
125 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 50;
126 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8;
127 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3;
128 constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000;
129
130 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
131 {"unspecified", OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
132 {"landscape", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
133 {"portrait", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
134 {"follow_recent", OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
135 {"landscape_inverted", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
136 {"portrait_inverted", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
137 {"auto_rotation", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
138 {"auto_rotation_landscape", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
139 {"auto_rotation_portrait", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
140 {"auto_rotation_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
141 {"auto_rotation_landscape_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
142 {"auto_rotation_portrait_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
143 {"locked", OHOS::AppExecFwk::DisplayOrientation::LOCKED},
144 {"auto_rotation_unspecified", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
145 {"follow_desktop", OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
146 };
147
148 const std::unordered_set<std::string> LAYOUT_INFO_WHITELIST = {
149 "SCBSmartDock",
150 "SCBExtScreenDock",
151 "status_bar_tray",
152 "status_bar_personal",
153 "status_bar_sound_panel",
154 "status_bar_notification_panel",
155 "status_bar_input_panel",
156 "status_bar_control_center",
157 "status_bar_wifi_panel",
158 "status_bar_input_method",
159 "status_bar_assistant_translate",
160 "status_bar_quick_note",
161 "status_bar_bluetooth_panel",
162 "status_bar_battery_panel",
163 "status_bar_focus_mode_paddle",
164 "SCBStatusBar"
165 };
166
167 static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
168
169 static std::shared_ptr<ScbDumpSubscriber> g_scbSubscriber(nullptr);
170
GetCurrentTime()171 std::string GetCurrentTime()
172 {
173 struct timespec tn;
174 clock_gettime(CLOCK_REALTIME, &tn);
175 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
176 static_cast<uint64_t>(tn.tv_nsec);
177 return std::to_string(uTime);
178 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)179 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
180 {
181 return a.first < b.first;
182 }
183
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)184 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
185 {
186 if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
187 value = (*item.intsValue_)[0];
188 return true;
189 }
190 return false;
191 }
192
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)193 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
194 {
195 auto& metadata = abilityInfo->metadata;
196 for (const auto& item : metadata) {
197 if (item.name == "enable.remove.starting.window") {
198 return item.value == "true";
199 }
200 }
201 return false;
202 }
203
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)204 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
205 AppExecFwk::ExtensionAbilityType extensionAbilityType)
206 {
207 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
208 element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
209 static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
210 AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
211 };
212 static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
213 std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
214 std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
215 std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
216 std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
217 std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
218 std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
219 std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
220 std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
221 std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
222 std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
223 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
224 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
225 std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
226 std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
227 std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
228 std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
229 std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
230 std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
231 std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
232 std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
233 };
234
235 if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
236 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: extensionAbilityType in white list");
237 return true;
238 }
239
240 auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
241 auto& [bundleName, abilityName, _] = item;
242 return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
243 });
244 if (it != elementNameWhitelist.end()) {
245 return true;
246 }
247
248 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
249 return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
250 PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
251 }
252
253 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
254 public:
255 BundleStatusCallback() = default;
256 virtual ~BundleStatusCallback() = default;
257
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)258 void OnBundleStateChanged(const uint8_t installType,
259 const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
260
OnBundleAdded(const std::string & bundleName,const int userId)261 void OnBundleAdded(const std::string& bundleName, const int userId) override
262 {
263 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
264 }
265
OnBundleUpdated(const std::string & bundleName,const int userId)266 void OnBundleUpdated(const std::string& bundleName, const int userId) override
267 {
268 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
269 }
270
OnBundleRemoved(const std::string & bundleName,const int userId)271 void OnBundleRemoved(const std::string& bundleName, const int userId) override
272 {
273 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
274 }
275 };
276
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)277 bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
278 {
279 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
280 !avoidArea.rightRect_.IsUninitializedRect()) {
281 return false;
282 }
283 if (avoidArea.bottomRect_.IsUninitializedRect()) {
284 return true;
285 }
286 auto diff =
287 std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
288 return isVisible && diff <= 1;
289 }
290 } // namespace
291
CreateInstance()292 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
293 {
294 sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
295 sessionManager->Init();
296 return sessionManager;
297 }
298
GetInstance()299 SceneSessionManager& SceneSessionManager::GetInstance()
300 {
301 static sptr<SceneSessionManager> instance = CreateInstance();
302 return *instance;
303 }
304
SceneSessionManager()305 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
306 {
307 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
308 if (!mainHandler_) {
309 auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
310 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
311 }
312 currentUserId_ = DEFAULT_USERID;
313 launcherService_ = new AppExecFwk::LauncherService();
314 if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
315 WLOGFE("Failed to register bundle status callback.");
316 }
317 ScbDumpSubscriber::Subscribe(g_scbSubscriber);
318 }
319
~SceneSessionManager()320 SceneSessionManager::~SceneSessionManager()
321 {
322 ScbDumpSubscriber::UnSubscribe(g_scbSubscriber);
323 }
324
Init()325 void SceneSessionManager::Init()
326 {
327 auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
328 bool isScbCoreEnabled = (deviceType == UI_TYPE_PHONE || deviceType == "tablet") &&
329 system::GetParameter("persist.window.scbcore.enable", "1") == "1";
330 Session::SetScbCoreEnabled(isScbCoreEnabled);
331
332 constexpr uint64_t interval = 5 * 1000; // 5 second
333 if (HiviewDFX::Watchdog::GetInstance().AddThread(
334 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
335 WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
336 }
337
338 bundleMgr_ = GetBundleManager();
339 LoadWindowSceneXml();
340 sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
341 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
342 InitPrepareTerminateConfig();
343 // create handler for inner command at server
344 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
345 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
346 if (eventHandler_ == nullptr) {
347 WLOGFE("Invalid eventHander");
348 return ;
349 }
350 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
351 if (ret != 0) {
352 WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
353 }
354
355 listenerController_ = std::make_shared<SessionListenerController>();
356 listenerController_->Init();
357 scbSessionHandler_ = new ScbSessionHandler();
358 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
359 StartWindowInfoReportLoop();
360 WLOGI("SSM init success.");
361 RegisterAppListener();
362 openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
363 isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1") == "1";
364 SceneInputManager::GetInstance().Init();
365
366 // MMI window state error check
367 int32_t retCode = MMI::InputManager::GetInstance()->
368 RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
369 this->NotifyWindowStateErrorFromMMI(pid, persistentId);
370 });
371 TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
372
373 AbilityInfoManager::GetInstance().Init(bundleMgr_);
374 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
375 UpdateDarkColorModeToRS();
376
377 InitSnapshotCache();
378 }
379
InitScheduleUtils()380 void SceneSessionManager::InitScheduleUtils()
381 {
382 #ifdef RES_SCHED_ENABLE
383 SCBThreadInfo threadInfo = {
384 .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
385 .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
386 };
387 std::unordered_map<std::string, std::string> payload {
388 { "pid", threadInfo.scbPid_ },
389 { "tid", threadInfo.scbTid_ },
390 { "uid", threadInfo.scbUid_ },
391 { "bundleName", threadInfo.scbBundleName_ },
392 };
393 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
394 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
395 auto task = [threadInfo = std::move(threadInfo)]() mutable {
396 threadInfo.ssmThreadName_ = "OS_SceneSession";
397 threadInfo.ssmTid_ = std::to_string(gettid());
398 const int32_t userInteraction = 2;
399 std::unordered_map<std::string, std::string> payload{
400 { "pid", threadInfo.scbPid_ },
401 { "tid", threadInfo.ssmTid_ },
402 { "uid", threadInfo.scbUid_ },
403 { "extType", "10002" },
404 { "cgroupPrio", "1" },
405 { "isSa", "0" },
406 { "threadName", threadInfo.ssmThreadName_ }
407 };
408 uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
409 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
410 TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
411 sptr<ISystemAbilityManager> systemAbilityManager =
412 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
413 if (!systemAbilityManager) {
414 TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
415 return;
416 }
417 auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
418 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
419 if (ret != ERR_OK) {
420 TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
421 }
422 };
423 taskScheduler_->PostAsyncTask(task, "changeQosTask");
424 #endif
425 }
426
RegisterAppListener()427 void SceneSessionManager::RegisterAppListener()
428 {
429 appAnrListener_ = new (std::nothrow) AppAnrListener();
430 auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
431 if (appMgrClient_ == nullptr) {
432 WLOGFE("appMgrClient_ is nullptr.");
433 } else if (appAnrListener_ == nullptr) {
434 WLOGFE("appAnrListener_ is nullptr.");
435 } else {
436 auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
437 if (flag != ERR_OK) {
438 WLOGFE("Register app debug listener failed.");
439 } else {
440 WLOGFI("Register app debug listener success.");
441 }
442 }
443 }
444
LoadWindowSceneXml()445 void SceneSessionManager::LoadWindowSceneXml()
446 {
447 if (WindowSceneConfig::LoadConfigXml()) {
448 if (WindowSceneConfig::GetConfig().IsMap()) {
449 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
450 }
451 ConfigWindowSceneXml();
452 } else {
453 WLOGFE("Load window scene xml failed");
454 }
455 ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
456 appWindowSceneConfig_.keyboardAnimationOut_);
457 }
458
InitPrepareTerminateConfig()459 void SceneSessionManager::InitPrepareTerminateConfig()
460 {
461 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
462 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
463 PREPARE_TERMINATE_ENABLE_SIZE);
464 WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
465 if (retSysParam > 0 && !std::strcmp(value, "true")) {
466 isPrepareTerminateEnable_ = true;
467 }
468 }
469
ConfigWindowSceneXml()470 void SceneSessionManager::ConfigWindowSceneXml()
471 {
472 const auto& config = WindowSceneConfig::GetConfig();
473 WindowSceneConfig::ConfigItem item = config["windowEffect"];
474 if (item.IsMap()) {
475 ConfigWindowEffect(item);
476 }
477
478 item = config["decor"];
479 if (item.IsMap()) {
480 ConfigDecor(item);
481 }
482
483 item = config["backgroundswitch"];
484 if (item.IsInts()) {
485 auto numbers = *item.intsValue_;
486 if (numbers.size() == 1 && numbers[0] == 1) {
487 systemConfig_.backgroundswitch = true;
488 }
489 }
490 WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
491
492 item = config["defaultWindowMode"];
493 if (item.IsInts()) {
494 auto numbers = *item.intsValue_;
495 if (numbers.size() == 1 &&
496 (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
497 numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
498 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
499 }
500 }
501
502 item = config["defaultMaximizeMode"];
503 if (item.IsInts()) {
504 auto numbers = *item.intsValue_;
505 if (numbers.size() == 1 &&
506 (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
507 numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
508 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
509 }
510 }
511
512 item = config["keyboardAnimation"];
513 if (item.IsMap()) {
514 ConfigKeyboardAnimation(item);
515 }
516
517 item = config["maxFloatingWindowSize"];
518 if (item.IsInts()) {
519 auto numbers = *item.intsValue_;
520 if (numbers.size() == 1) {
521 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
522 }
523 }
524
525 item = config["windowAnimation"];
526 if (item.IsMap()) {
527 ConfigWindowAnimation(item);
528 }
529
530 item = config["startWindowTransitionAnimation"];
531 if (item.IsMap()) {
532 ConfigStartingWindowAnimation(item);
533 }
534 item = config["maxMidSceneNum"];
535 if (item.IsInts()) {
536 auto numbers = *item.intsValue_;
537 if (numbers.size() == 1) {
538 systemConfig_.maxMidSceneNum_ = static_cast<uint32_t>(numbers[0]);
539 }
540 }
541 ConfigFreeMultiWindow();
542 ConfigWindowSizeLimits();
543 ConfigSnapshotScale();
544 ConfigWindowSceneXml(config);
545 }
546
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)547 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
548 {
549 WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
550 if (item.IsMap()) {
551 ConfigSystemUIStatusBar(item);
552 }
553 item = config["uiType"];
554 if (item.IsString()) {
555 systemConfig_.uiType_ = item.stringValue_;
556 appWindowSceneConfig_.uiType_ = item.stringValue_;
557 }
558 item = config["backgroundScreenLock"].GetProp("enable");
559 if (item.IsBool()) {
560 appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
561 }
562 item = config["rotationMode"];
563 if (item.IsString()) {
564 appWindowSceneConfig_.rotationMode_ = item.stringValue_;
565 }
566 item = config["immersive"];
567 if (item.IsMap()) {
568 ConfigWindowImmersive(item);
569 }
570 item = config["supportTypeFloatWindow"].GetProp("enable");
571 if (item.IsBool()) {
572 systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
573 }
574 }
575
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)576 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
577 {
578 AppWindowSceneConfig config;
579 WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
580 if (item.IsMap()) {
581 if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
582 appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
583 config.windowImmersive_.desktopStatusBarConfig_;
584 }
585 }
586 item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
587 if (item.IsMap()) {
588 if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
589 appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
590 config.windowImmersive_.upDownStatusBarConfig_;
591 }
592 }
593 item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
594 if (item.IsMap()) {
595 if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
596 appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
597 config.windowImmersive_.leftRightStatusBarConfig_;
598 }
599 }
600 }
601
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)602 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
603 StatusBarConfig& statusBarConfig)
604 {
605 WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
606 if (item.IsBool()) {
607 statusBarConfig.showHide_ = item.boolValue_;
608 }
609 item = config["contentColor"];
610 if (item.IsString()) {
611 statusBarConfig.contentColor_ = item.stringValue_;
612 }
613 item = config["backgroundColor"];
614 if (item.IsString()) {
615 statusBarConfig.backgroundColor_ = item.stringValue_;
616 }
617 return true;
618 }
619
ConfigFreeMultiWindow()620 void SceneSessionManager::ConfigFreeMultiWindow()
621 {
622 const auto& config = WindowSceneConfig::GetConfig();
623 WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
624 if (freeMultiWindowConfig.IsMap()) {
625 auto supportItem = freeMultiWindowConfig.GetProp("enable");
626 if (supportItem.IsBool()) {
627 systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
628 }
629 auto item = freeMultiWindowConfig["decor"];
630 if (item.IsMap()) {
631 ConfigDecor(item, false);
632 }
633 int32_t param = -1;
634 item = freeMultiWindowConfig["defaultWindowMode"];
635 if (GetSingleIntItem(item, param) &&
636 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
637 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
638 systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
639 static_cast<WindowMode>(static_cast<uint32_t>(param));
640 }
641 item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
642 if (GetSingleIntItem(item, param) && (param > 0)) {
643 systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
644 }
645 }
646 }
647
LoadFreeMultiWindowConfig(bool enable)648 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
649 {
650 FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
651 if (enable) {
652 systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
653 systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
654 systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
655 } else {
656 const auto& config = WindowSceneConfig::GetConfig();
657 auto item = config["decor"];
658 if (item.IsMap()) {
659 ConfigDecor(item, true);
660 }
661 int32_t param = -1;
662 item = config["defaultWindowMode"];
663 if (GetSingleIntItem(item, param) &&
664 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
665 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
666 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
667 }
668 }
669 systemConfig_.freeMultiWindowEnable_ = enable;
670 }
671
GetSystemSessionConfig() const672 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
673 {
674 return systemConfig_;
675 }
676
SwitchFreeMultiWindow(bool enable)677 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
678 {
679 if (!systemConfig_.freeMultiWindowSupport_) {
680 TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
681 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
682 }
683 LoadFreeMultiWindowConfig(enable);
684 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
685 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
686 auto sceneSession = item->second;
687 if (sceneSession == nullptr) {
688 continue;
689 }
690 auto property = sceneSession->GetSessionProperty();
691 if (property == nullptr) {
692 continue;
693 }
694 bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
695 property->GetExtensionFlag();
696 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
697 sceneSession->SwitchFreeMultiWindow(enable);
698 }
699 }
700 WindowStyleType type = enable ?
701 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
702 SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
703 return WSError::WS_OK;
704 }
705
GetFreeMultiWindowEnableState(bool & enable)706 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
707 {
708 enable = systemConfig_.freeMultiWindowEnable_;
709 return WSError::WS_OK;
710 }
711
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)712 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
713 const ContinueState& continueState)
714 {
715 TLOGI(WmsLogTag::DEFAULT, "Enter");
716 auto task = [this, token, continueState]() {
717 sptr <SceneSession> sceneSession = FindSessionByToken(token);
718 if (sceneSession == nullptr) {
719 TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
720 return WSError::WS_ERROR_INVALID_PARAM;
721 }
722 sceneSession->SetSessionInfoContinueState(continueState);
723 DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
724 static_cast<AAFwk::ContinueState>(continueState));
725 TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
726 sceneSession->GetPersistentId(), continueState);
727 return WSError::WS_OK;
728 };
729 return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
730 }
731
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)732 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
733 {
734 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
735 if (item.IsBool()) {
736 if (mainConfig) {
737 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
738 } else {
739 systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
740 }
741 bool decorEnable = item.boolValue_;
742 uint32_t support = 0;
743 std::vector<std::string> supportedModes;
744 item = decorConfig["supportedMode"];
745 if (item.IsStrings()) {
746 supportedModes = *item.stringsValue_;
747 }
748 for (auto mode : supportedModes) {
749 if (mode == "fullscreen") {
750 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
751 } else if (mode == "floating") {
752 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
753 } else if (mode == "pip") {
754 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
755 } else if (mode == "split") {
756 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
757 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
758 } else {
759 WLOGFW("Invalid supporedMode");
760 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
761 break;
762 }
763 }
764 if (mainConfig && item.IsStrings()) {
765 systemConfig_.decorWindowModeSupportType_ = support;
766 }
767 if (!mainConfig && item.IsStrings()) {
768 systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
769 }
770 }
771 }
772
AddAlphaToColor(float alpha,std::string & color)773 static void AddAlphaToColor(float alpha, std::string& color)
774 {
775 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
776 return;
777 }
778
779 uint32_t alphaValue = 0xFF * alpha;
780 std::stringstream ss;
781 ss << std::hex << alphaValue;
782 std::string strAlpha = ss.str();
783 if (strAlpha.size() == 1) {
784 strAlpha.append(1, '0');
785 }
786
787 color.insert(1, strAlpha);
788 }
789
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)790 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
791 {
792 return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
793 (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
794 AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
795 }
796
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)797 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
798 {
799 AppWindowSceneConfig config;
800 // config corner radius
801 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
802 if (item.IsMap()) {
803 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
804 appWindowSceneConfig_ = config;
805 }
806 }
807
808 // config shadow
809 item = effectConfig["appWindows"]["shadow"]["focused"];
810 if (item.IsMap()) {
811 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
812 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
813 }
814 }
815
816 item = effectConfig["appWindows"]["shadow"]["unfocused"];
817 if (item.IsMap()) {
818 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
819 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
820 }
821 }
822
823 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
824 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
825
826 WLOGFI("Config window effect successfully");
827 }
828
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)829 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
830 {
831 std::map<std::string, float> stringToCornerRadius = {
832 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
833 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
834 };
835
836 if (item.IsString()) {
837 auto value = item.stringValue_;
838 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
839 out = stringToCornerRadius[value];
840 return true;
841 }
842 }
843 return false;
844 }
845
SetEnableInputEvent(bool enabled)846 void SceneSessionManager::SetEnableInputEvent(bool enabled)
847 {
848 TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
849 enableInputEvent_ = enabled;
850 }
851
IsInputEventEnabled()852 bool SceneSessionManager::IsInputEventEnabled()
853 {
854 return enableInputEvent_;
855 }
856
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)857 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
858 {
859 for (const auto& persistentId : alivePersistentIds_) {
860 auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
861 if (it != recoveredPersistentIds.end()) {
862 continue;
863 }
864 auto sceneSession = GetSceneSession(persistentId);
865 if (sceneSession == nullptr) {
866 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
867 continue;
868 }
869 if (sceneSession->IsRecovered()) {
870 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
871 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
872 EraseSceneSessionAndMarkDirtyLocked(persistentId);
873 }
874 }
875 }
876
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)877 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
878 {
879 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
880 recoveredPersistentIds.size(), currentUserId_.load());
881
882 auto task = [this, recoveredPersistentIds]() {
883 ClearUnrecoveredSessions(recoveredPersistentIds);
884 std::list<AAFwk::SessionInfo> abilitySessionInfos;
885 for (const auto& persistentId : recoveredPersistentIds) {
886 if (failRecoveredPersistentIdSet_.count(persistentId)) {
887 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
888 continue;
889 }
890 auto sceneSession = GetSceneSession(persistentId);
891 if (sceneSession == nullptr) {
892 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
893 continue;
894 }
895 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
896 if (!abilitySessionInfo) {
897 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
898 continue;
899 }
900 TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
901 abilitySessionInfos.emplace_back(*abilitySessionInfo);
902 }
903 std::vector<int32_t> unrecoverableSessionIds;
904 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
905 abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
906 TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
907 unrecoverableSessionIds.size());
908 for (const auto& sessionId : unrecoverableSessionIds) {
909 auto sceneSession = GetSceneSession(sessionId);
910 if (sceneSession == nullptr) {
911 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
912 sessionId);
913 continue;
914 }
915 const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
916 if (!scnSessionInfo) {
917 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
918 continue;
919 }
920 TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
921 sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
922 }
923 RemoveFailRecoveredSession();
924 };
925 return taskScheduler_->PostAsyncTask(task);
926 }
927
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)928 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
929 WindowShadowConfig& outShadow)
930 {
931 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
932 if (item.IsString()) {
933 auto color = item.stringValue_;
934 uint32_t colorValue;
935 if (!ColorParser::Parse(color, colorValue)) {
936 return false;
937 }
938 outShadow.color_ = color;
939 }
940
941 item = shadowConfig["offsetX"];
942 if (item.IsFloats()) {
943 auto offsetX = *item.floatsValue_;
944 if (offsetX.size() != 1) {
945 return false;
946 }
947 outShadow.offsetX_ = offsetX[0];
948 }
949
950 item = shadowConfig["offsetY"];
951 if (item.IsFloats()) {
952 auto offsetY = *item.floatsValue_;
953 if (offsetY.size() != 1) {
954 return false;
955 }
956 outShadow.offsetY_ = offsetY[0];
957 }
958
959 item = shadowConfig["alpha"];
960 if (item.IsFloats()) {
961 auto alpha = *item.floatsValue_;
962 if (alpha.size() != 1 ||
963 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
964 return false;
965 }
966 outShadow.alpha_ = alpha[0];
967 }
968
969 item = shadowConfig["radius"];
970 if (item.IsFloats()) {
971 auto radius = *item.floatsValue_;
972 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
973 return false;
974 }
975 outShadow.radius_ = radius[0];
976 }
977
978 return true;
979 }
980
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)981 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
982 KeyboardSceneAnimationConfig& config)
983 {
984 if (item.IsMap() && item.mapValue_->count("curve")) {
985 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
986 config.curveType_ = curveType;
987 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
988 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
989 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
990 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
991 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
992 }
993 }
994
995 const WindowSceneConfig::ConfigItem& duration = item["duration"];
996 if (duration.IsInts()) {
997 auto numbers = *duration.intsValue_;
998 if (numbers.size() == 1) {
999 config.duration_ = static_cast<uint32_t>(numbers[0]);
1000 }
1001 }
1002 }
1003
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)1004 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
1005 {
1006 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
1007 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
1008
1009 // config system animation
1010 const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
1011 systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
1012 {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
1013 appConfigIn.duration_);
1014 const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
1015 systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
1016 {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
1017 appConfigOut.duration_);
1018 }
1019
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)1020 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
1021 KeyboardSceneAnimationConfig& animationOut)
1022 {
1023 if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
1024 TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
1025 "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
1026 systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
1027 systemConfig_.animationOut_.duration_);
1028 return;
1029 }
1030
1031 // default animation curve params
1032 constexpr char CURVETYPE[] = "interpolatingSpring";
1033 constexpr float IN_CTRLX1 = 0.0f;
1034 constexpr float OUT_CTRLX1 = 4.0f;
1035 constexpr float CTRLY1 = 1.0f;
1036 constexpr float CTRLX2 = 342.0f;
1037 constexpr float CTRLY2 = 37.0f;
1038 constexpr uint32_t DURATION = 150;
1039 std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1040 std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1041
1042 // update system config for client
1043 systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1044 systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1045
1046 // update app config for server
1047 animationIn.curveType_ = CURVETYPE;
1048 animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1049 animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1050 animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1051 animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1052 animationIn.duration_ = DURATION;
1053
1054 animationOut.curveType_ = CURVETYPE;
1055 animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1056 animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1057 animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1058 animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1059 animationOut.duration_ = DURATION;
1060 TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
1061 }
1062
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1063 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1064 {
1065 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1066 if (item.IsMap() && item.mapValue_->count("curve")) {
1067 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1068 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1069 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1070 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1071 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1072 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1073 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1074 }
1075 }
1076 item = windowAnimationConfig["timing"]["duration"];
1077 if (item.IsInts() && item.intsValue_->size() == 1) {
1078 auto duration = *item.intsValue_;
1079 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1080 }
1081 item = windowAnimationConfig["scale"];
1082 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1083 auto scales = *item.floatsValue_;
1084 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1085 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1086 }
1087 item = windowAnimationConfig["rotation"];
1088 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1089 auto rotations = *item.floatsValue_;
1090 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1091 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1092 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1093 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1094 }
1095 item = windowAnimationConfig["translate"];
1096 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1097 auto translates = *item.floatsValue_;
1098 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1099 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1100 }
1101 item = windowAnimationConfig["opacity"];
1102 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1103 auto opacity = *item.floatsValue_;
1104 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1105 }
1106 }
1107
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1108 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1109 {
1110 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1111 auto item = configItem.GetProp("enable");
1112 if (item.IsBool()) {
1113 config.enabled_ = item.boolValue_;
1114 }
1115 item = configItem["timing"];
1116 if (item.IsMap() && item.mapValue_->count("curve")) {
1117 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1118 }
1119 item = configItem["timing"]["duration"];
1120 if (item.IsInts() && item.intsValue_->size() == 1) {
1121 config.duration_ = (*item.intsValue_)[0];
1122 }
1123 item = configItem["opacityStart"];
1124 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1125 config.opacityStart_ = (*item.floatsValue_)[0];
1126 }
1127 item = configItem["opacityEnd"];
1128 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1129 config.opacityEnd_ = (*item.floatsValue_)[0];
1130 }
1131 }
1132
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1133 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1134 const WindowSceneConfig::ConfigItem& curveConfig)
1135 {
1136 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1137 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1138 static std::unordered_set<std::string> paramCurveSet = {
1139 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1140
1141 std::string curveName = "easeOut";
1142 const auto& nameItem = curveConfig.GetProp("name");
1143 if (!nameItem.IsString()) {
1144 return {curveName, {}};
1145 }
1146
1147 std::string name = nameItem.stringValue_;
1148 std::vector<float> curveParams;
1149
1150 if (paramCurveSet.find(name) != paramCurveSet.end()) {
1151 curveName = name;
1152 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1153 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1154 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1155 curveParams.begin());
1156 }
1157 } else {
1158 auto iter = curveSet.find(name);
1159 if (iter != curveSet.end()) {
1160 curveName = name;
1161 }
1162 }
1163
1164 return {curveName, curveParams};
1165 }
1166
ConfigWindowSizeLimits()1167 void SceneSessionManager::ConfigWindowSizeLimits()
1168 {
1169 const auto& config = WindowSceneConfig::GetConfig();
1170 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1171 if (item.IsMap()) {
1172 ConfigMainWindowSizeLimits(item);
1173 }
1174
1175 item = config["subWindowSizeLimits"];
1176 if (item.IsMap()) {
1177 ConfigSubWindowSizeLimits(item);
1178 }
1179 }
1180
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1181 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1182 {
1183 auto item = mainWindowSizeConifg["miniWidth"];
1184 if (item.IsInts()) {
1185 auto numbers = *item.intsValue_;
1186 if (numbers.size() == 1) {
1187 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1188 }
1189 }
1190
1191 item = mainWindowSizeConifg["miniHeight"];
1192 if (item.IsInts()) {
1193 auto numbers = *item.intsValue_;
1194 if (numbers.size() == 1) {
1195 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1196 }
1197 }
1198 }
1199
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1200 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1201 {
1202 auto item = subWindowSizeConifg["miniWidth"];
1203 if (item.IsInts()) {
1204 auto numbers = *item.intsValue_;
1205 if (numbers.size() == 1) {
1206 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1207 }
1208 }
1209
1210 item = subWindowSizeConifg["miniHeight"];
1211 if (item.IsInts()) {
1212 auto numbers = *item.intsValue_;
1213 if (numbers.size() == 1) {
1214 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1215 }
1216 }
1217 }
1218
ConfigSnapshotScale()1219 void SceneSessionManager::ConfigSnapshotScale()
1220 {
1221 const auto& config = WindowSceneConfig::GetConfig();
1222 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1223 if (item.IsFloats()) {
1224 auto snapshotScale = *item.floatsValue_;
1225 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1226 return;
1227 }
1228 snapshotScale_ = snapshotScale[0];
1229 }
1230 }
1231
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1232 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1233 {
1234 TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1235 WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1236 if (item.IsInts() && item.intsValue_->size() == 1) {
1237 bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1238 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1239 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1240 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1241 }
1242
1243 item = statusBarConfig["immersiveStatusBarBgColor"];
1244 if (item.IsString()) {
1245 auto color = item.stringValue_;
1246 uint32_t colorValue;
1247 if (!ColorParser::Parse(color, colorValue)) {
1248 return;
1249 }
1250 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1251 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1252 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1253 }
1254
1255 item = statusBarConfig["immersiveStatusBarContentColor"];
1256 if (item.IsString()) {
1257 auto color = item.stringValue_;
1258 uint32_t colorValue;
1259 if (!ColorParser::Parse(color, colorValue)) {
1260 return;
1261 }
1262 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1263 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1264 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1265 }
1266 }
1267
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1268 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1269 {
1270 rootSceneContextWeak_ = contextWeak;
1271 }
1272
GetRootSceneSession()1273 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1274 {
1275 auto task = [this]() -> sptr<RootSceneSession> {
1276 if (rootSceneSession_ != nullptr) {
1277 return rootSceneSession_;
1278 }
1279 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1280 rootSceneSession_ = new RootSceneSession();
1281 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1282 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1283 return rootSceneSession_;
1284 };
1285
1286 return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1287 }
1288
GetRootSessionAvoidSessionRect(AvoidAreaType type)1289 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1290 {
1291 sptr<RootSceneSession> rootSession = GetRootSceneSession();
1292 if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1293 return {};
1294 }
1295 DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1296 std::vector<sptr<SceneSession>> sessionVector;
1297 switch (type) {
1298 case AvoidAreaType::TYPE_SYSTEM: {
1299 sessionVector = GetSceneSessionVectorByTypeAndDisplayId(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1300 break;
1301 }
1302 case AvoidAreaType::TYPE_KEYBOARD: {
1303 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
1304 break;
1305 }
1306 default: {
1307 TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1308 return {};
1309 }
1310 }
1311
1312 for (auto& session : sessionVector) {
1313 if (!session->IsVisible()) {
1314 continue;
1315 }
1316 const WSRect rect = session->GetSessionRect();
1317 TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1318 return rect;
1319 }
1320 return {};
1321 }
1322
GetSceneSession(int32_t persistentId)1323 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1324 {
1325 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1326 auto iter = sceneSessionMap_.find(persistentId);
1327 if (iter == sceneSessionMap_.end()) {
1328 WLOGFD("Error found scene session with id: %{public}d", persistentId);
1329 return nullptr;
1330 }
1331 return iter->second;
1332 }
1333
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1334 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1335 const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1336 {
1337 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1338 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1339 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1340 sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1341 SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1342 mainSessions.push_back(sceneSession);
1343 }
1344 }
1345 }
1346
GetMainSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,std::vector<sptr<SceneSession>> & mainSessions) const1347 void SceneSessionManager::GetMainSessionByAbilityInfo(const AbilityInfoBase& abilityInfo,
1348 std::vector<sptr<SceneSession>>& mainSessions) const
1349 {
1350 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1351 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1352 if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1353 continue;
1354 }
1355 if (sceneSession->GetSessionInfo().bundleName_ == abilityInfo.bundleName &&
1356 sceneSession->GetSessionInfo().moduleName_ == abilityInfo.moduleName &&
1357 sceneSession->GetSessionInfo().abilityName_ == abilityInfo.abilityName &&
1358 sceneSession->GetSessionInfo().appIndex_ == abilityInfo.appIndex) {
1359 mainSessions.push_back(sceneSession);
1360 }
1361 }
1362 }
1363
GetSceneSessionByName(const ComparedSessionInfo & info)1364 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const ComparedSessionInfo& info)
1365 {
1366 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1367 for (const auto &item : sceneSessionMap_) {
1368 auto sceneSession = item.second;
1369 if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1370 sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1371 sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1372 continue;
1373 }
1374 if (info.isAtomicService_) {
1375 if ((sceneSession->GetSessionInfo().moduleName_.empty() ||
1376 sceneSession->GetSessionInfo().moduleName_ == info.moduleName_) &&
1377 (sceneSession->GetSessionInfo().abilityName_.empty() ||
1378 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_)) {
1379 return sceneSession;
1380 }
1381 } else if (sceneSession->GetSessionInfo().moduleName_ == info.moduleName_ &&
1382 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_) {
1383 return sceneSession;
1384 }
1385 }
1386 return nullptr;
1387 }
1388
GetSceneSessionByType(WindowType type)1389 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1390 {
1391 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1392 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1393 if (sceneSession && sceneSession->GetWindowType() == type) {
1394 return sceneSession;
1395 }
1396 }
1397 return nullptr;
1398 }
1399
GetSceneSessionByBundleName(const std::string & bundleName)1400 sptr<SceneSession> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1401 {
1402 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1403 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1404 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1405 return sceneSession;
1406 }
1407 }
1408 return nullptr;
1409 }
1410
GetSceneSessionVectorByTypeAndDisplayId(WindowType type,uint64_t displayId)1411 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByTypeAndDisplayId(
1412 WindowType type, uint64_t displayId)
1413 {
1414 if (displayId == DISPLAY_ID_INVALID) {
1415 TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1416 return {};
1417 }
1418 std::vector<sptr<SceneSession>> sceneSessionVector;
1419 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1420 for (const auto &item : sceneSessionMap_) {
1421 auto sceneSession = item.second;
1422 if (sceneSession->GetWindowType() == type &&
1423 sceneSession->GetSessionProperty() &&
1424 sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1425 sceneSessionVector.emplace_back(sceneSession);
1426 }
1427 }
1428
1429 return sceneSessionVector;
1430 }
1431
GetSceneSessionVectorByType(WindowType type)1432 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
1433 {
1434 std::vector<sptr<SceneSession>> sceneSessionVector;
1435 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1436 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1437 if (sceneSession->GetWindowType() == type) {
1438 sceneSessionVector.emplace_back(sceneSession);
1439 }
1440 }
1441 return sceneSessionVector;
1442 }
1443
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1444 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1445 sptr<WindowSessionProperty> property)
1446 {
1447 if (property == nullptr) {
1448 TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1449 return WSError::WS_ERROR_NULLPTR;
1450 }
1451 if (sceneSession == nullptr) {
1452 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1453 return WSError::WS_ERROR_NULLPTR;
1454 }
1455 auto parentPersistentId = property->GetParentPersistentId();
1456 sceneSession->SetParentPersistentId(parentPersistentId);
1457 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1458 auto parentSession = GetSceneSession(parentPersistentId);
1459 if (parentSession == nullptr) {
1460 TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1461 return WSError::WS_ERROR_NULLPTR;
1462 }
1463 parentSession->BindDialogSessionTarget(sceneSession);
1464 parentSession->BindDialogToParentSession(sceneSession);
1465 sceneSession->SetParentSession(parentSession);
1466 TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1467 sceneSession->GetPersistentId(), parentPersistentId);
1468 }
1469 return WSError::WS_OK;
1470 }
1471
CreateSpecificSessionCallback()1472 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1473 {
1474 sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
1475 if (specificCb == nullptr) {
1476 WLOGFE("SpecificSessionCallback is nullptr");
1477 return nullptr;
1478 }
1479 specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1480 return this->RequestSceneSession(sessionInfo, property);
1481 };
1482 specificCb->onDestroy_ = [this](const int32_t persistentId) {
1483 return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1484 };
1485 specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1486 this->ClearDisplayStatusBarTemporarilyFlags();
1487 };
1488 specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1489 this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1490 };
1491 specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1492 return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1493 };
1494 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1495 return this->GetSceneSessionVectorByType(type);
1496 };
1497 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1498 this->UpdateAvoidArea(persistentId);
1499 };
1500 specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1501 return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1502 };
1503 specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1504 this->UpdateOccupiedAreaIfNeed(persistentId);
1505 };
1506 specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1507 this->NotifyWindowInfoChange(persistentId, type);
1508 };
1509 specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1510 this->NotifyMMIWindowPidChange(windowId, startMoving);
1511 };
1512 specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1513 this->NotifySessionTouchOutside(persistentId);
1514 };
1515 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1516 return this->GetAINavigationBarArea(displayId);
1517 };
1518 specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1519 this->OnOutsideDownEvent(x, y);
1520 };
1521 specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1522 return this->HandleSecureSessionShouldHide(sceneSession);
1523 };
1524 specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1525 this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1526 };
1527 specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1528 this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1529 };
1530 specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1531 this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1532 };
1533 specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1534 this->UpdateGestureBackEnabled(persistentId);
1535 };
1536 return specificCb;
1537 }
1538
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1539 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1540 {
1541 TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1542 auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1543 if (isSkip) {
1544 if (it == skipSurfaceNodeIds_.end()) {
1545 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1546 } else {
1547 return;
1548 }
1549 } else {
1550 if (it != skipSurfaceNodeIds_.end()) {
1551 skipSurfaceNodeIds_.erase(it);
1552 } else {
1553 return;
1554 }
1555 }
1556 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1557 }
1558
CreateKeyboardSessionCallback()1559 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1560 {
1561 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1562 new (std::nothrow)KeyboardSession::KeyboardSessionCallback();
1563 if (keyboardCb == nullptr) {
1564 TLOGE(WmsLogTag::WMS_KEYBOARD, "KeyboardSessionCallback is nullptr");
1565 return keyboardCb;
1566 }
1567 keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1568 return this->GetSceneSession(persistentId);
1569 };
1570 keyboardCb->onGetFocusedSessionId_ = [this] {
1571 return this->GetFocusedSessionId();
1572 };
1573 keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1574
1575 return keyboardCb;
1576 }
1577
CheckWindowId(int32_t windowId,int32_t & pid)1578 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1579 {
1580 if (!SessionPermission::IsSystemCalling()) {
1581 TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1582 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1583 }
1584
1585 auto task = [this, windowId, &pid]() -> WMError {
1586 pid = INVALID_PID;
1587 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1588 auto iter = sceneSessionMap_.find(windowId);
1589 if (iter == sceneSessionMap_.end()) {
1590 WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
1591 return WMError::WM_ERROR_INVALID_WINDOW;
1592 }
1593 auto sceneSession = iter->second;
1594 if (sceneSession == nullptr) {
1595 WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1596 return WMError::WM_ERROR_INVALID_WINDOW;
1597 }
1598 pid = sceneSession->GetCallingPid();
1599 WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1600 return WMError::WM_OK;
1601 };
1602 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1603 }
1604
GetLockScreenZOrder()1605 uint32_t SceneSessionManager::GetLockScreenZOrder()
1606 {
1607 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1608 for (const auto& [persistentId, session] : sceneSessionMap_) {
1609 if (session && session->IsScreenLockWindow()) {
1610 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: found window %{public}d", persistentId);
1611 return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
1612 session->GetZOrder();
1613 }
1614 }
1615 TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
1616 return DEFAULT_LOCK_SCREEN_ZORDER;
1617 }
1618
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)1619 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
1620 const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
1621 {
1622 std::ostringstream ss;
1623 ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
1624 return taskScheduler_->PostSyncTask([this, windowId, callingTokenId, &element, extensionAbilityType, &pid]() {
1625 pid = INVALID_PID;
1626 auto sceneSession = GetSceneSession(windowId);
1627 if (sceneSession == nullptr) {
1628 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
1629 return WMError::WM_ERROR_INVALID_WINDOW;
1630 }
1631 pid = sceneSession->GetCallingPid();
1632 if (!IsScreenLocked()) {
1633 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
1634 return WMError::WM_OK;
1635 }
1636 if (IsUserAuthPassed()) {
1637 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
1638 return WMError::WM_OK;
1639 }
1640 // 1. check window whether can show on main window
1641 if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
1642 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
1643 return WMError::WM_OK;
1644 }
1645 // 2. check permission
1646 if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
1647 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
1648 callingTokenId);
1649 return WMError::WM_ERROR_INVALID_PERMISSION;
1650 }
1651 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: IsShowOnLockScreen: The caller permission has granted");
1652 return WMError::WM_OK;
1653 }, ss.str());
1654 }
1655
1656 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)1657 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
1658 {
1659 taskScheduler_->PostSyncTask([this, &windowIds]() {
1660 // check every window
1661 for (auto windowId : windowIds) {
1662 auto sceneSession = GetSceneSession(windowId);
1663 if (!sceneSession) {
1664 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
1665 continue;
1666 }
1667 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
1668 sceneSession->OnNotifyAboveLockScreen();
1669 }
1670 return WMError::WM_OK;
1671 }, __func__);
1672 }
1673
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1674 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1675 {
1676 if (!isKeyboardPanelEnabled_) {
1677 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1678 return;
1679 }
1680 if (keyboardSession == nullptr) {
1681 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1682 return;
1683 }
1684 auto sessionProperty = keyboardSession->GetSessionProperty();
1685 if (sessionProperty == nullptr) {
1686 TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1687 return;
1688 }
1689 DisplayId displayId = sessionProperty->GetDisplayId();
1690 const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
1691 sptr<SceneSession> panelSession;
1692 if (panelVec.size() > 1) {
1693 TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1694 return;
1695 } else if (panelVec.size() == 1) {
1696 panelSession = panelVec.front();
1697 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1698 } else {
1699 SessionInfo panelInfo = {
1700 .bundleName_ = "SCBKeyboardPanel",
1701 .moduleName_ = "SCBKeyboardPanel",
1702 .abilityName_ = "SCBKeyboardPanel",
1703 .isSystem_ = true,
1704 .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1705 .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1706 .screenId_ = static_cast<uint64_t>(displayId),
1707 .isRotable_ = true,
1708 };
1709 static bool is2in1 = systemConfig_.uiType_ == UI_TYPE_PC;
1710 if (is2in1) {
1711 panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1712 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1713 } else {
1714 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1715 }
1716 panelSession = RequestSceneSession(panelInfo, nullptr);
1717 if (panelSession == nullptr) {
1718 TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1719 return;
1720 }
1721 }
1722 keyboardSession->BindKeyboardPanelSession(panelSession);
1723 panelSession->BindKeyboardSession(keyboardSession);
1724 TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1725 panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1726 }
1727
OnSCBSystemSessionBufferAvailable(WindowType type)1728 void SceneSessionManager::OnSCBSystemSessionBufferAvailable(WindowType type)
1729 {
1730 TLOGI(WmsLogTag::WMS_MULTI_USER, "In");
1731 if (type == WindowType::WINDOW_TYPE_KEYGUARD) {
1732 TLOGI(WmsLogTag::WMS_MULTI_USER, "On screen lock buffer available");
1733 }
1734 }
1735
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1736 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1737 sptr<WindowSessionProperty> property)
1738 {
1739 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1740 sptr<SceneSession> sceneSession = nullptr;
1741 if (sessionInfo.isSystem_) {
1742 sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
1743 WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1744 if (sceneSession != nullptr &&
1745 static_cast<OHOS::Rosen::WindowType>(sessionInfo.windowType_) == WindowType::WINDOW_TYPE_KEYGUARD) {
1746 TLOGI(WmsLogTag::WMS_MULTI_USER, "Register screen lock buffer available");
1747 sceneSession->RegisterBufferAvailableCallback([this] {
1748 this->OnSCBSystemSessionBufferAvailable(WindowType::WINDOW_TYPE_KEYGUARD);
1749 });
1750 }
1751 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1752 sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
1753 if (sceneSession != nullptr) {
1754 TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1755 }
1756 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1757 sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
1758 TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1759 } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1760 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1761 sceneSession = new (std::nothrow) KeyboardSession(sessionInfo, specificCb, keyboardCb);
1762 CreateKeyboardPanelSession(sceneSession);
1763 TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1764 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1765 sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
1766 TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1767 } else {
1768 TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1769 }
1770 if (sceneSession != nullptr) {
1771 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1772 sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1773 sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1774 return this->GetAppForceLandscapeConfig(bundleName);
1775 });
1776 sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1777 this->UpdatePrivateStateAndNotify(persistentId);
1778 });
1779 sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1780 this->NotifyVisibleChange(persistentId);
1781 });
1782 sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
1783 return this->IsLastFrameLayoutFinished(isLayoutFinished);
1784 });
1785 sceneSession->SetIsAINavigationBarAvoidAreaValidFunc([this](const AvoidArea& avoidArea, int32_t sessionBottom) {
1786 return CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea, sessionBottom);
1787 });
1788 DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1789 GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
1790 sceneSession->SetAppDragResizeType(dragResizeType);
1791 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
1792 sceneSession->GetPersistentId(), sceneSession->GetSessionProperty()->GetDisplayId());
1793 sceneSession->SetSingleHandTransform(singleHandTransform_);
1794 }
1795 return sceneSession;
1796 }
1797
GetEffectiveDragResizeType(DragResizeType & dragResizeType)1798 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
1799 {
1800 if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1801 return;
1802 }
1803 if (systemConfig_.freeMultiWindowSupport_) {
1804 dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
1805 } else {
1806 dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
1807 }
1808 }
1809
SetGlobalDragResizeType(DragResizeType dragResizeType)1810 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
1811 {
1812 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1813 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1814 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1815 return WMError::WM_ERROR_INVALID_PERMISSION;
1816 }
1817 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1818 globalDragResizeType_ = dragResizeType;
1819 taskScheduler_->PostAsyncTask([this] {
1820 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1821 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1822 if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1823 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
1824 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1825 GetAppDragResizeType(bundleName, appDragResizeType);
1826 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1827 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
1828 sceneSession->SetAppDragResizeType(appDragResizeType);
1829 }
1830 }
1831 }, __func__);
1832 return WMError::WM_OK;
1833 }
1834
GetGlobalDragResizeType(DragResizeType & dragResizeType)1835 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
1836 {
1837 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1838 dragResizeType = globalDragResizeType_;
1839 GetEffectiveDragResizeType(dragResizeType);
1840 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1841 return WMError::WM_OK;
1842 }
1843
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)1844 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
1845 {
1846 TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1847 dragResizeType, bundleName.c_str());
1848 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1849 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1850 return WMError::WM_ERROR_INVALID_PERMISSION;
1851 }
1852 return SetAppDragResizeTypeInner(bundleName, dragResizeType);
1853 }
1854
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)1855 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
1856 {
1857 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1858 dragResizeType, bundleName.c_str());
1859 if (bundleName.empty()) {
1860 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1861 return WMError::WM_ERROR_INVALID_PARAM;
1862 }
1863 std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
1864 appDragResizeTypeMap_[bundleName] = dragResizeType;
1865 GetAppDragResizeTypeInner(bundleName, dragResizeType);
1866 taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
1867 auto sceneSession = GetSceneSessionByBundleName(bundleName);
1868 if (sceneSession != nullptr) {
1869 TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1870 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
1871 sceneSession->SetAppDragResizeType(dragResizeType);
1872 }
1873 }, __func__);
1874 return WMError::WM_OK;
1875 }
1876
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)1877 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
1878 {
1879 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1880 return GetAppDragResizeTypeInner(bundleName, dragResizeType);
1881 }
1882
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)1883 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
1884 {
1885 if (bundleName.empty()) {
1886 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1887 return WMError::WM_ERROR_INVALID_PARAM;
1888 }
1889 if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1890 TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
1891 dragResizeType = globalDragResizeType_;
1892 return WMError::WM_OK;
1893 }
1894 dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1895 if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
1896 dragResizeType = iter->second;
1897 }
1898 GetEffectiveDragResizeType(dragResizeType);
1899 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1900 dragResizeType, bundleName.c_str());
1901 return WMError::WM_OK;
1902 }
1903
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)1904 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
1905 {
1906 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1907 auto session = GetSceneSession(sessionInfo.persistentId_);
1908 if (session != nullptr) {
1909 TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1910 return session;
1911 }
1912
1913 if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1914 TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1915 "abilityName: %{public}s, appIndex: %{public}d",
1916 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1917 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1918 ComparedSessionInfo compareSessionInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_,
1919 sessionInfo.appIndex_, sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1920 auto sceneSession = GetSceneSessionByName(compareSessionInfo);
1921 bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1922 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1923 if (isSingleStart) {
1924 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1925 sessionInfo.persistentId_);
1926 return sceneSession;
1927 }
1928 }
1929 }
1930 return nullptr;
1931 }
1932
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1933 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1934 sptr<WindowSessionProperty> property)
1935 {
1936 const char* const where = __func__;
1937 auto task = [this, sessionInfo, property, where] {
1938 if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
1939 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1940 return session;
1941 }
1942 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
1943 "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1944 where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1945 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1946 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1947 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1948 if (sceneSession == nullptr) {
1949 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1950 return sceneSession;
1951 }
1952 InitSceneSession(sceneSession, sessionInfo, property);
1953 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1954 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1955 where, sceneSession->GetSessionInfo().ancoSceneState);
1956 bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1957 const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1958 if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1959 TLOGNI(WmsLogTag::WMS_LIFE,
1960 "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1961 where, reusedSceneSession->GetPersistentId(),
1962 reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1963 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1964 return reusedSceneSession;
1965 }
1966 if (isPreHandleSuccess) {
1967 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1968 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1969 }
1970 }
1971 {
1972 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1973 sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1974 }
1975 PerformRegisterInRequestSceneSession(sceneSession);
1976 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1977 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d, type: %{public}d, displayId: %{public}" PRIu64,
1978 where, sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
1979 sceneSession->GetSessionProperty()->GetDisplayId());
1980 return sceneSession;
1981 };
1982 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1983 }
1984
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)1985 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1986 const sptr<WindowSessionProperty>& property)
1987 {
1988 auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1989 DisplayId curDisplayId = DISPLAY_ID_INVALID;
1990 if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1991 curDisplayId = sessionInfo.screenId_;
1992 } else if (callerSession) {
1993 auto callerSessionProperty = callerSession->GetSessionProperty();
1994 if (callerSessionProperty) {
1995 curDisplayId = callerSessionProperty->GetDisplayId();
1996 }
1997 }
1998 auto sessionProperty = sceneSession->GetSessionProperty();
1999 if (sessionProperty) {
2000 sessionProperty->SetDisplayId(curDisplayId);
2001 sceneSession->SetScreenId(curDisplayId);
2002 TLOGI(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
2003 curDisplayId);
2004 }
2005 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
2006 sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
2007 if (sessionInfo.isSystem_) {
2008 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
2009 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
2010 auto rootContext = rootSceneContextWeak_.lock();
2011 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
2012 } else {
2013 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
2014 "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
2015 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2016 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
2017 }
2018 RegisterSessionExceptionFunc(sceneSession);
2019 // Skip FillSessionInfo when atomicService free-install start.
2020 if (!IsAtomicServiceFreeInstall(sessionInfo)) {
2021 FillSessionInfo(sceneSession);
2022 }
2023 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
2024 if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
2025 sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
2026 }
2027 sceneSession->SetSystemConfig(systemConfig_);
2028 sceneSession->SetSnapshotScale(snapshotScale_);
2029 UpdateParentSessionForDialog(sceneSession, property);
2030 std::string key = sessionInfo.bundleName_ + "_" + sessionInfo.moduleName_ + "_" + sessionInfo.abilityName_ + "_" +
2031 std::to_string(sessionInfo.appIndex_);
2032 if (sessionLockedStateCacheSet_.find(key) != sessionLockedStateCacheSet_.end()) {
2033 sceneSession->NotifySessionLockStateChange(true);
2034 }
2035 }
2036
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)2037 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
2038 {
2039 sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
2040 if (info == nullptr) {
2041 WLOGFE("new info failed");
2042 return;
2043 }
2044 info->action_ = action;
2045 info->abilityName_ = sessionInfo.abilityName_;
2046 info->bundleName_ = sessionInfo.bundleName_;
2047 info->toScreenId_ = sessionInfo.screenId_;
2048 info->fromScreenId_ = fromScreenId;
2049 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
2050 WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
2051 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
2052 }
2053
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)2054 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
2055 {
2056 RegisterSessionSnapshotFunc(sceneSession);
2057 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
2058 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
2059 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
2060 RegisterGetStateFromManagerFunc(sceneSession);
2061 RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
2062 RegisterAcquireRotateAnimationConfigFunc(sceneSession);
2063 }
2064
UpdateSceneSessionWant(const SessionInfo & sessionInfo)2065 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
2066 {
2067 if (sessionInfo.persistentId_ != 0) {
2068 auto session = GetSceneSession(sessionInfo.persistentId_);
2069 if (session != nullptr && sessionInfo.want != nullptr) {
2070 TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
2071 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
2072 session->SetSessionInfoWant(sessionInfo.want);
2073 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
2074 } else {
2075 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
2076 }
2077 } else {
2078 TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
2079 session == nullptr, sessionInfo.persistentId_);
2080 }
2081 } else {
2082 TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
2083 }
2084 }
2085
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2086 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2087 {
2088 if (session != nullptr) {
2089 if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2090 FillSessionInfo(session);
2091 if (CheckCollaboratorType(session->GetCollaboratorType())) {
2092 PreHandleCollaborator(session, persistentId);
2093 }
2094 }
2095 }
2096 }
2097
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)2098 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
2099 {
2100 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
2101 if (abilitySessionInfo == nullptr) {
2102 WLOGFE("abilitySessionInfo is nullptr");
2103 return nullptr;
2104 }
2105 auto sessionInfo = scnSession->GetSessionInfo();
2106 sptr<ISession> iSession(scnSession);
2107 abilitySessionInfo->sessionToken = iSession->AsObject();
2108 abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2109 std::chrono::system_clock::now()).time_since_epoch().count());
2110 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2111 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2112 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2113 abilitySessionInfo->persistentId = scnSession->GetPersistentId();
2114 abilitySessionInfo->requestCode = sessionInfo.requestCode;
2115 abilitySessionInfo->resultCode = sessionInfo.resultCode;
2116 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2117 abilitySessionInfo->startSetting = sessionInfo.startSetting;
2118 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2119 abilitySessionInfo->userId = currentUserId_;
2120 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2121 abilitySessionInfo->processOptions = sessionInfo.processOptions;
2122 abilitySessionInfo->tmpSpecifiedId = sessionInfo.specifiedId;
2123 if (sessionInfo.want != nullptr) {
2124 abilitySessionInfo->want = *sessionInfo.want;
2125 } else {
2126 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2127 sessionInfo.moduleName_);
2128 }
2129 int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2130 bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2131 if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2132 TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2133 appIndex, sessionInfo.appIndex_);
2134 }
2135 if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2136 TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2137 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2138 }
2139 auto sessionProperty = scnSession->GetSessionProperty();
2140 if (sessionProperty) {
2141 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2142 static_cast<int>(sessionProperty->GetDisplayId()));
2143 }
2144 if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2145 sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2146 abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2147 } else {
2148 TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2149 }
2150 return abilitySessionInfo;
2151 }
2152
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2153 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2154 {
2155 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2156 isPrepareTerminate = false;
2157 TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2158 return WSError::WS_OK;
2159 }
2160 auto sceneSession = GetSceneSession(persistentId);
2161 if (sceneSession == nullptr) {
2162 TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2163 isPrepareTerminate = false;
2164 return WSError::WS_ERROR_NULLPTR;
2165 }
2166 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2167 if (sceneSessionInfo == nullptr) {
2168 TLOGE(WmsLogTag::WMS_MAIN, "sceneSessionInfo is null, Id:%{public}d", persistentId);
2169 isPrepareTerminate = false;
2170 return WSError::WS_ERROR_NULLPTR;
2171 }
2172 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2173 PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2174 TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2175 "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2176 return WSError::WS_OK;
2177 }
2178
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)2179 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
2180 {
2181 wptr<SceneSession> weakSceneSession(sceneSession);
2182 auto task = [this, weakSceneSession, isNewActive]() {
2183 sptr<SceneSession> scnSession = weakSceneSession.promote();
2184 if (scnSession == nullptr) {
2185 TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2186 return WSError::WS_ERROR_NULLPTR;
2187 }
2188 auto persistentId = scnSession->GetPersistentId();
2189 if (!Session::IsScbCoreEnabled()) {
2190 scnSession->SetForegroundInteractiveStatus(true);
2191 }
2192 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2193 TLOGI(WmsLogTag::WMS_MAIN,
2194 "Request active id:%{public}d, system:%{public}u, isNewActive:%{public}d, specifiedId:%{public}d",
2195 persistentId, scnSession->GetSessionInfo().isSystem_,
2196 isNewActive, scnSession->GetSessionInfo().specifiedId);
2197 if (!GetSceneSession(persistentId)) {
2198 TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2199 return WSError::WS_ERROR_INVALID_SESSION;
2200 }
2201 auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
2202 if (ret == WSError::WS_OK) {
2203 scnSession->SetExitSplitOnBackground(false);
2204 }
2205 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
2206 return ret;
2207 };
2208 std::string taskName = "RequestSceneSessionActivation:PID:" +
2209 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2210 taskScheduler_->PostAsyncTask(task, taskName);
2211 return WSError::WS_OK;
2212 }
2213
IsKeyboardForeground()2214 bool SceneSessionManager::IsKeyboardForeground()
2215 {
2216 bool isKeyboardForeground = false;
2217 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2218 for (const auto &item : sceneSessionMap_) {
2219 auto sceneSession = item.second;
2220 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2221 isKeyboardForeground = sceneSession->IsSessionForeground();
2222 break;
2223 }
2224 }
2225
2226 return isKeyboardForeground;
2227 }
2228
RequestInputMethodCloseKeyboard(const int32_t persistentId)2229 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
2230 {
2231 auto sceneSession = GetSceneSession(persistentId);
2232 if (sceneSession == nullptr) {
2233 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
2234 return;
2235 }
2236 // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
2237 if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
2238 !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
2239 TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
2240 persistentId, sceneSession->GetSessionState());
2241 sceneSession->RequestHideKeyboard(true);
2242 }
2243 }
2244
StartUIAbilityBySCB(sptr<SceneSession> & scnSession)2245 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
2246 {
2247 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2248 if (abilitySessionInfo == nullptr) {
2249 return ERR_NULL_OBJECT;
2250 }
2251 return StartUIAbilityBySCB(abilitySessionInfo);
2252 }
2253
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)2254 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
2255 {
2256 bool isColdStart = false;
2257 return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
2258 }
2259
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession> & scnSession,bool visibility)2260 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
2261 {
2262 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2263 if (abilitySessionInfo == nullptr) {
2264 return ERR_NULL_OBJECT;
2265 }
2266 return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
2267 }
2268
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive)2269 WSError SceneSessionManager::RequestSceneSessionActivationInner(
2270 sptr<SceneSession>& scnSession, bool isNewActive)
2271 {
2272 auto persistentId = scnSession->GetPersistentId();
2273 RequestInputMethodCloseKeyboard(persistentId);
2274 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2275 scnSession->SetIsStarting(true);
2276 scnSession->SetStartingBeforeVisible(true);
2277 }
2278 if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
2279 if (Session::IsScbCoreEnabled()) {
2280 if (scnSession->IsVisibleForeground()) {
2281 RequestSessionFocusImmediately(persistentId);
2282 } else {
2283 PostProcessFocusState state = { true, true, FocusChangeReason::SCB_START_APP };
2284 scnSession->SetPostProcessFocusState(state);
2285 }
2286 } else {
2287 RequestSessionFocusImmediately(persistentId);
2288 }
2289 }
2290 if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2291 FillSessionInfo(scnSession);
2292 if (!PreHandleCollaborator(scnSession, persistentId)) {
2293 TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
2294 persistentId, scnSession->GetSessionInfo().ancoSceneState);
2295 scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
2296 return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
2297 }
2298 }
2299 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2300 if (!scnSessionInfo) {
2301 TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
2302 return WSError::WS_ERROR_NULLPTR;
2303 }
2304 scnSession->NotifyActivation();
2305 scnSessionInfo->isNewWant = isNewActive;
2306 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2307 scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
2308 scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
2309 }
2310 TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
2311 "module: %{public}s, uri: %{public}s, appIndex: %{public}d, tmpSpecifiedId:%{public}d", persistentId,
2312 scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
2313 scnSessionInfo->want.GetElement().GetBundleName().c_str(),
2314 scnSessionInfo->want.GetElement().GetModuleName().c_str(),
2315 scnSessionInfo->want.GetElement().GetURI().c_str(),
2316 scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0),
2317 scnSessionInfo->tmpSpecifiedId);
2318 int32_t errCode = ERR_OK;
2319 bool isColdStart = false;
2320 bool isAppSupportPhoneInPc = false;
2321 auto sessionProperty = scnSession->GetSessionProperty();
2322 if (sessionProperty != nullptr) {
2323 isAppSupportPhoneInPc = sessionProperty->GetIsAppSupportPhoneInPc();
2324 }
2325 if (systemConfig_.backgroundswitch == false || isAppSupportPhoneInPc) {
2326 TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
2327 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2328 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2329 } else {
2330 TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
2331 isNewActive, scnSession->GetSessionState());
2332 if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
2333 scnSession->GetSessionState() == SessionState::STATE_END) {
2334 TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
2335 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2336 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2337 } else {
2338 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
2339 scnSession->NotifySessionForeground(1, true);
2340 }
2341 }
2342 auto sessionInfo = scnSession->GetSessionInfo();
2343 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2344 WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
2345 }
2346 NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
2347
2348 if (errCode != ERR_OK) {
2349 TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
2350 scnSession->NotifySessionExceptionInner(scnSessionInfo, true, false, true);
2351 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
2352 startUIAbilityErrorFunc_(
2353 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
2354 }
2355 }
2356 if (isColdStart) {
2357 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
2358 scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
2359 scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
2360 scnSession->ResetSessionConnectState();
2361 scnSession->ResetIsActive();
2362 }
2363 return WSError::WS_OK;
2364 }
2365
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)2366 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
2367 sptr<AAFwk::SessionInfo>& scnSessionInfo)
2368 {
2369 if (scnSession == nullptr || scnSessionInfo == nullptr) {
2370 return;
2371 }
2372 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2373 NotifyLoadAbility(scnSession->GetCollaboratorType(),
2374 scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
2375 NotifyUpdateSessionInfo(scnSession);
2376 NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2377 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2378 }
2379 }
2380
InitSnapshotCache()2381 void SceneSessionManager::InitSnapshotCache()
2382 {
2383 const static std::string invalidUitype = "";
2384 const static std::unordered_map<std::string, std::size_t> SNAPSHOT_CACHE_CAPACITY_MAP = {
2385 {UI_TYPE_PC, MAX_SNAPSHOT_IN_RECENT_PC},
2386 {UI_TYPE_PAD, MAX_SNAPSHOT_IN_RECENT_PAD},
2387 {UI_TYPE_PHONE, MAX_SNAPSHOT_IN_RECENT_PHONE},
2388 {invalidUitype, MAX_SNAPSHOT_IN_RECENT_PHONE},
2389 };
2390
2391 auto uiType = systemConfig_.uiType_;
2392 snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(invalidUitype);
2393 if (SNAPSHOT_CACHE_CAPACITY_MAP.find(uiType) != SNAPSHOT_CACHE_CAPACITY_MAP.end()) {
2394 snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(systemConfig_.uiType_);
2395 }
2396 TLOGI(WmsLogTag::WMS_PATTERN, "type: %{public}s, capacity: %{public}u",
2397 systemConfig_.uiType_.c_str(), snapshotCapacity_);
2398 snapshotLRUCache_ = std::make_unique<LRUCache>(snapshotCapacity_);
2399 }
2400
PutSnapshotToCache(int32_t persistentId)2401 void SceneSessionManager::PutSnapshotToCache(int32_t persistentId)
2402 {
2403 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2404 if (int32_t removedCacheId = snapshotLRUCache_->Put(persistentId);
2405 removedCacheId != UNDEFINED_REMOVED_KEY) {
2406 if (auto removedCacheSession = GetSceneSession(removedCacheId)) {
2407 removedCacheSession->ResetSnapshot();
2408 } else {
2409 TLOGW(WmsLogTag::WMS_PATTERN, "removedCacheSession:%{public}d nullptr", removedCacheId);
2410 }
2411 }
2412 }
2413
VisitSnapshotFromCache(int32_t persistentId)2414 void SceneSessionManager::VisitSnapshotFromCache(int32_t persistentId)
2415 {
2416 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2417 if (!snapshotLRUCache_->Visit(persistentId)) {
2418 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d not in cache", persistentId);
2419 }
2420 }
2421
RemoveSnapshotFromCache(int32_t persistentId)2422 void SceneSessionManager::RemoveSnapshotFromCache(int32_t persistentId)
2423 {
2424 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2425 snapshotLRUCache_->Remove(persistentId);
2426 if (auto sceneSession = GetSceneSession(persistentId)) {
2427 sceneSession->ResetSnapshot();
2428 }
2429 }
2430
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)2431 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2432 const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2433 {
2434 wptr<SceneSession> weakSceneSession(sceneSession);
2435 auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
2436 auto scnSession = weakSceneSession.promote();
2437 if (scnSession == nullptr) {
2438 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
2439 return WSError::WS_ERROR_NULLPTR;
2440 }
2441 auto persistentId = scnSession->GetPersistentId();
2442 TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2443 "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2444 persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2445 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2446 scnSession->SetActive(false);
2447
2448 if (isToDesktop) {
2449 auto info = scnSession->GetSessionInfo();
2450 info.callerToken_ = nullptr;
2451 info.callingTokenId_ = 0;
2452 scnSession->SetSessionInfo(info);
2453 }
2454
2455 scnSession->SetSaveSnapshotCallback([this, persistentId]() {
2456 this->PutSnapshotToCache(persistentId);
2457 });
2458
2459 scnSession->BackgroundTask(isSaveSnapshot);
2460 if (!GetSceneSession(persistentId)) {
2461 TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2462 return WSError::WS_ERROR_INVALID_SESSION;
2463 }
2464 if (persistentId == brightnessSessionId_) {
2465 UpdateBrightness(focusedSessionId_);
2466 }
2467 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2468 if (!scnSessionInfo) {
2469 TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2470 return WSError::WS_ERROR_NULLPTR;
2471 }
2472 bool isPcAppInpad = false;
2473 bool isAppSupportPhoneInPc = false;
2474 auto property = scnSession->GetSessionProperty();
2475 if (property) {
2476 isPcAppInpad = property->GetIsPcAppInPad();
2477 isAppSupportPhoneInPc = property->GetIsAppSupportPhoneInPc();
2478 }
2479 if ((systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || isPcAppInpad) {
2480 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2481 scnSession->NotifySessionBackground(1, true, true);
2482 } else {
2483 TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2484 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2485 if (!isDelegator) {
2486 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2487 } else {
2488 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2489 }
2490 }
2491
2492 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2493 auto sessionInfo = scnSession->GetSessionInfo();
2494 WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2495 }
2496 return WSError::WS_OK;
2497 };
2498 std::string taskName = "RequestSceneSessionBackground:PID:" +
2499 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2500 taskScheduler_->PostAsyncTask(task, taskName);
2501 return WSError::WS_OK;
2502 }
2503
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2504 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2505 {
2506 wptr<SceneSession> weakSceneSession(sceneSession);
2507 auto task = [this, weakSceneSession, interactive]() {
2508 auto scnSession = weakSceneSession.promote();
2509 if (scnSession == nullptr) {
2510 WLOGFE("session is nullptr");
2511 return;
2512 }
2513 auto persistentId = scnSession->GetPersistentId();
2514 WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2515 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2516 if (!GetSceneSession(persistentId)) {
2517 WLOGFE("session is invalid with %{public}d", persistentId);
2518 return;
2519 }
2520 scnSession->NotifyForegroundInteractiveStatus(interactive);
2521 };
2522
2523 taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2524 }
2525
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)2526 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2527 {
2528 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2529 if (scnSession == nullptr) {
2530 TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2531 return WSError::WS_ERROR_NULLPTR;
2532 }
2533 if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2534 TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2535 auto dialogVec = scnSession->GetDialogVector();
2536 for (auto dialog : dialogVec) {
2537 if (dialog == nullptr) {
2538 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2539 continue;
2540 }
2541 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2542 if (sceneSession == nullptr) {
2543 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2544 return WSError::WS_ERROR_INVALID_SESSION;
2545 }
2546 WindowDestroyNotifyVisibility(sceneSession);
2547 dialog->NotifyDestroy();
2548 dialog->Disconnect();
2549
2550 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2551 if (dialogSceneSession != nullptr) {
2552 dialogSceneSession->ClearSpecificSessionCbMap();
2553 }
2554 {
2555 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2556 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2557 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2558 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2559 }
2560 }
2561 scnSession->ClearDialogVector();
2562 return WSError::WS_OK;
2563 }
2564 return WSError::WS_ERROR_INVALID_SESSION;
2565 }
2566
DestroySubSession(const sptr<SceneSession> & sceneSession)2567 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2568 {
2569 if (sceneSession == nullptr) {
2570 TLOGW(WmsLogTag::WMS_SUB, "sceneSession is nullptr");
2571 return;
2572 }
2573 for (const auto& elem : sceneSession->GetSubSession()) {
2574 if (elem != nullptr) {
2575 const auto& persistentId = elem->GetPersistentId();
2576 TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2577 DestroyAndDisconnectSpecificSessionInner(persistentId);
2578 }
2579 }
2580 }
2581
DestroyToastSession(const sptr<SceneSession> & sceneSession)2582 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2583 {
2584 if (sceneSession == nullptr) {
2585 TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2586 return;
2587 }
2588 for (const auto& elem : sceneSession->GetToastSession()) {
2589 if (elem != nullptr) {
2590 const auto& persistentId = elem->GetPersistentId();
2591 TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2592 DestroyAndDisconnectSpecificSessionInner(persistentId);
2593 }
2594 }
2595 }
2596
BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t fingerId,int32_t action,int32_t wid)2597 void SceneSessionManager::BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2598 int32_t fingerId, int32_t action, int32_t wid)
2599 {
2600 if (pointerEvent == nullptr) {
2601 TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null, wid:%{public}d fingerId:%{public}d action:%{public}d",
2602 wid, fingerId, action);
2603 return;
2604 }
2605 pointerEvent->SetId(CANCEL_POINTER_ID);
2606 pointerEvent->SetTargetWindowId(wid);
2607 pointerEvent->SetPointerId(fingerId);
2608 pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
2609 MMI::PointerEvent::PointerItem item;
2610 item.SetPointerId(fingerId);
2611 pointerEvent->AddPointerItem(item);
2612 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
2613 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
2614 } else {
2615 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
2616 }
2617 }
2618
SendCancelEventBeforeEraseSession(const sptr<SceneSession> & sceneSession)2619 void SceneSessionManager::SendCancelEventBeforeEraseSession(const sptr<SceneSession>& sceneSession)
2620 {
2621 auto task = [this, needCancelEventSceneSession = sceneSession] {
2622 if (needCancelEventSceneSession == nullptr) {
2623 TLOGI(WmsLogTag::WMS_EVENT, "scenesession is nullptr, needn't send cancel event");
2624 return;
2625 }
2626 auto wid = needCancelEventSceneSession->GetPersistentId();
2627 if (needCancelEventSceneSession->GetMousePointerDownEventStatus()) {
2628 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2629 BuildCancelPointerEvent(pointerEvent, 1, MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN, wid);
2630 TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send mouse cancel. wid:%{public}d", wid);
2631 needCancelEventSceneSession->SetMousePointerDownEventStatus(false);
2632 needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2633 }
2634 std::unordered_set<int32_t> fingerPointerDownStatusList = needCancelEventSceneSession->GetFingerPointerDownStatusList();
2635 if (fingerPointerDownStatusList.empty()) {
2636 return;
2637 }
2638 for (auto fingerId : fingerPointerDownStatusList) {
2639 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2640 BuildCancelPointerEvent(pointerEvent, fingerId, MMI::PointerEvent::POINTER_ACTION_DOWN, wid);
2641 TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send touch cancel. wid:%{public}d fingerId:%{public}d",
2642 wid, fingerId);
2643 needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2644 needCancelEventSceneSession->RemoveFingerPointerDownStatus(fingerId);
2645 }
2646 };
2647 mainHandler_->PostTask(std::move(task), "wms:sendCancelBeforeEraseSession", 0, AppExecFwk::EventQueue::Priority::VIP);
2648 }
2649
EraseSceneSessionMapById(int32_t persistentId)2650 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2651 {
2652 auto sceneSession = GetSceneSession(persistentId);
2653 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2654 EraseSceneSessionAndMarkDirtyLocked(persistentId);
2655 systemTopSceneSessionMap_.erase(persistentId);
2656 nonSystemFloatSceneSessionMap_.erase(persistentId);
2657 SendCancelEventBeforeEraseSession(sceneSession);
2658 }
2659
2660 /**
2661 * if visible session is erased, mark dirty
2662 * lock-free
2663 */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2664 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2665 {
2666 // get scene session lock-free
2667 auto iter = sceneSessionMap_.find(persistentId);
2668 if (iter == sceneSessionMap_.end()) {
2669 TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2670 return;
2671 }
2672 sptr<SceneSession> sceneSession = iter->second;
2673 if (sceneSession != nullptr && sceneSession->IsVisible()) {
2674 sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2675 }
2676 sceneSessionMap_.erase(persistentId);
2677 }
2678
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean)2679 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2680 bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2681 {
2682 auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2683 needRemoveSession, isSaveSnapshot, isForceClean]() {
2684 auto scnSession = weakSceneSession.promote();
2685 if (scnSession == nullptr) {
2686 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2687 return WSError::WS_ERROR_NULLPTR;
2688 }
2689 auto persistentId = scnSession->GetPersistentId();
2690 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2691 RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2692 avoidAreaListenerSessionSet_.erase(persistentId);
2693 DestroyDialogWithMainWindow(scnSession);
2694 DestroyToastSession(scnSession);
2695 DestroySubSession(scnSession); // destroy sub session by destruction
2696 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2697 " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2698 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2699 WindowDestroyNotifyVisibility(scnSession);
2700 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2701 scnSession->SetRemoveSnapshotCallback([this, persistentId]() {
2702 this->RemoveSnapshotFromCache(persistentId);
2703 });
2704 scnSession->DisconnectTask(false, isSaveSnapshot);
2705 if (!GetSceneSession(persistentId)) {
2706 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2707 return WSError::WS_ERROR_INVALID_SESSION;
2708 }
2709 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2710 if (!scnSessionInfo) {
2711 return WSError::WS_ERROR_NULLPTR;
2712 }
2713 scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2714 ResetSceneSessionInfoWant(scnSessionInfo);
2715 return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2716 };
2717 std::string taskName = "RequestSceneSessionDestruction:PID:" +
2718 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2719 taskScheduler_->PostAsyncTask(task, taskName);
2720 return WSError::WS_OK;
2721 }
2722
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)2723 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
2724 {
2725 if (sceneSessionInfo->resultCode == -1) {
2726 AAFwk::Want want;
2727 std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2728 want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2729 sceneSessionInfo->want = std::move(want);
2730 TLOGI(WmsLogTag::WMS_MAIN, "keySessionId: %{public}s", keySessionId.c_str());
2731 }
2732 }
2733
ResetWant(sptr<SceneSession> & sceneSession)2734 void SceneSessionManager::ResetWant(sptr<SceneSession>& sceneSession)
2735 {
2736 auto& sessionInfo = sceneSession->GetSessionInfo();
2737 if (sessionInfo.want != nullptr) {
2738 const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2739 const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2740 const auto& keySessionId = sessionInfo.want->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2741 auto want = std::make_shared<AAFwk::Want>();
2742 if (want != nullptr) {
2743 AppExecFwk::ElementName element;
2744 element.SetBundleName(bundleName);
2745 element.SetAbilityName(abilityName);
2746 want->SetElement(element);
2747 want->SetBundle(bundleName);
2748 if (!keySessionId.empty()) {
2749 want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2750 }
2751 sceneSession->SetSessionInfoWant(want);
2752 }
2753 }
2754 }
2755
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession,const bool isForceClean)2756 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& scnSession,
2757 sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2758 {
2759 auto persistentId = scnSession->GetPersistentId();
2760 TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}u",
2761 persistentId,
2762 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2763 if (isForceClean) {
2764 AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2765 } else {
2766 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2767 }
2768 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2769 if (needRemoveSession) {
2770 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2771 NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2772 }
2773 EraseSceneSessionMapById(persistentId);
2774 } else {
2775 // if terminate, reset want. so start from recent, start a new one.
2776 TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2777 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2778 scnSession->SetSessionInfoWant(nullptr);
2779 }
2780 ResetWant(scnSession);
2781 scnSession->ResetSessionInfoResultCode();
2782 }
2783 if (listenerController_ != nullptr) {
2784 NotifySessionForCallback(scnSession, needRemoveSession);
2785 }
2786 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2787 return WSError::WS_OK;
2788 }
2789
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)2790 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2791 const sptr<SceneSession>& sceneSession)
2792 {
2793 if (sceneSession == nullptr || sessionStage == nullptr) {
2794 TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2795 return;
2796 }
2797
2798 auto remoteObject = sessionStage->AsObject();
2799 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2800 if (windowDeath_ == nullptr) {
2801 TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2802 return;
2803 }
2804 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2805 TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2806 return;
2807 }
2808 WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2809 }
2810
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)2811 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2812 {
2813 auto task = [this, remoteObject]() {
2814 auto iter = remoteObjectMap_.find(remoteObject);
2815 if (iter == remoteObjectMap_.end()) {
2816 WLOGFE("Invalid remoteObject");
2817 return;
2818 }
2819 WLOGFD("Remote died, id: %{public}d", iter->second);
2820 auto session = GetSceneSession(iter->second);
2821 if (session == nullptr) {
2822 WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2823 return;
2824 }
2825 DestroyAndDisconnectSpecificSessionInner(iter->second);
2826 };
2827 taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2828 }
2829
CreateAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,int32_t & persistentId,sptr<ISession> & session,SystemSessionConfig & systemConfig,sptr<IRemoteObject> token)2830 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2831 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2832 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2833 SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2834 {
2835 if (property == nullptr) {
2836 WLOGFE("property is nullptr");
2837 return WSError::WS_ERROR_NULLPTR;
2838 }
2839
2840 if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2841 WLOGFE("create system window or modal subwindow permission denied!");
2842 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2843 }
2844
2845 bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2846 property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2847 bool isSystemCalling = SessionPermission::IsSystemCalling();
2848 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2849 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2850 if (parentSession) {
2851 shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2852 }
2853 }
2854 bool isPcWindow = false;
2855 IsPcWindow(isPcWindow);
2856 if (isPcWindow && property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
2857 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't block");
2858 shouldBlock = false;
2859 }
2860 if (shouldBlock) {
2861 TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2862 return WSError::WS_ERROR_INVALID_OPERATION;
2863 }
2864
2865 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2866 property->GetExtensionFlag() && property->GetIsUIExtensionAbilityProcess() &&
2867 SessionPermission::IsStartedByUIExtension()) {
2868 auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2869 if (extensionParentSession == nullptr) {
2870 WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2871 return WSError::WS_ERROR_NULLPTR;
2872 }
2873 SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2874 AAFwk::UIExtensionHostInfo hostInfo;
2875 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2876 if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2877 WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2878 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2879 hostInfo.elementName_.GetBundleName().c_str());
2880 return WSError::WS_ERROR_INVALID_WINDOW;
2881 }
2882 }
2883
2884 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2885 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2886 WLOGFE("The alarm window has been deprecated!");
2887 return WSError::WS_ERROR_INVALID_WINDOW;
2888 }
2889
2890 if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2891 WLOGFE("pip window is not enable to create.");
2892 return WSError::WS_DO_NOTHING;
2893 }
2894 TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2895 property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2896
2897 // Get pid and uid before posting task.
2898 auto pid = IPCSkeleton::GetCallingRealPid();
2899 auto uid = IPCSkeleton::GetCallingUid();
2900 auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2901 &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2902 if (property == nullptr) {
2903 WLOGFE("[WMSSub][WMSSystem] property is nullptr");
2904 return WSError::WS_ERROR_NULLPTR;
2905 }
2906 const auto& type = property->GetWindowType();
2907 // create specific session
2908 SessionInfo info;
2909 info.windowType_ = static_cast<uint32_t>(type);
2910 info.bundleName_ = property->GetSessionInfo().bundleName_;
2911 info.abilityName_ = property->GetSessionInfo().abilityName_;
2912 info.moduleName_ = property->GetSessionInfo().moduleName_;
2913 info.screenId_ = property->GetDisplayId();
2914
2915 ClosePipWindowIfExist(type);
2916 sptr<SceneSession> newSession = RequestSceneSession(info, property);
2917 if (newSession == nullptr) {
2918 TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2919 return WSError::WS_ERROR_NULLPTR;
2920 }
2921 property->SetSystemCalling(isSystemCalling);
2922 auto errCode = newSession->ConnectInner(
2923 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2924 newSession->SetIsSystemSpecificSession(isSystemCalling);
2925 systemConfig = systemConfig_;
2926 if (property) {
2927 persistentId = property->GetPersistentId();
2928 }
2929
2930 NotifyCreateSpecificSession(newSession, property, type);
2931 session = newSession;
2932 AddClientDeathRecipient(sessionStage, newSession);
2933 TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2934 "parentId: %{public}d, type: %{public}d",
2935 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2936 return errCode;
2937 };
2938
2939 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2940 }
2941
ClosePipWindowIfExist(WindowType type)2942 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2943 {
2944 if (type != WindowType::WINDOW_TYPE_PIP) {
2945 return;
2946 }
2947 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2948 for (const auto& iter: sceneSessionMap_) {
2949 auto& session = iter.second;
2950 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2951 session->NotifyCloseExistPipWindow();
2952 break;
2953 }
2954 }
2955 }
2956
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)2957 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2958 {
2959 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2960 for (const auto& iter: sceneSessionMap_) {
2961 auto& session = iter.second;
2962 if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2963 pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2964 session->IsSessionForeground()) {
2965 if (startPiPFailedFunc_) {
2966 startPiPFailedFunc_();
2967 }
2968 TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2969 return false;
2970 }
2971 }
2972 return true;
2973 }
2974
isEnablePiPCreate(const sptr<WindowSessionProperty> & property)2975 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2976 {
2977 if (isScreenLocked_) {
2978 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2979 return false;
2980 }
2981 Rect pipRect = property->GetRequestRect();
2982 if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2983 TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2984 return false;
2985 }
2986 if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2987 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2988 return false;
2989 }
2990 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2991 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2992 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2993 return false;
2994 }
2995 return true;
2996 }
2997
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)2998 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2999 {
3000 WindowType type = property->GetWindowType();
3001 if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
3002 return true;
3003 }
3004
3005 if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
3006 TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
3007 return false;
3008 }
3009
3010 if (!SessionPermission::IsSystemCalling()) {
3011 TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
3012 return false;
3013 }
3014
3015 return true;
3016 }
3017
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)3018 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
3019 {
3020 WindowType type = property->GetWindowType();
3021 if (WindowHelper::IsUIExtensionWindow(type)) {
3022 // UIExtension window disallowed.
3023 return false;
3024 }
3025 if (!WindowHelper::IsSystemWindow(type)) {
3026 // type is not system
3027 return true;
3028 }
3029 if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)
3030 && SessionPermission::IsStartedByInputMethod()) {
3031 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
3032 WLOGFD("check create permission success, input method app create input method window.");
3033 return true;
3034 }
3035 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
3036 // some system types could be created by normal app
3037 return true;
3038 }
3039 if (type == WindowType::WINDOW_TYPE_FLOAT &&
3040 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
3041 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
3042 if (systemConfig_.supportTypeFloatWindow_) {
3043 WLOGFD("check create float window permission success on 2in1 device.");
3044 return true;
3045 }
3046 }
3047 if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
3048 int32_t parentId = property->GetParentPersistentId();
3049 auto parentSession = GetSceneSession(parentId);
3050 if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
3051 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
3052 TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
3053 return true;
3054 } else {
3055 TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
3056 }
3057 }
3058 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
3059 TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
3060 return true;
3061 }
3062 WLOGFE("check system window permission failed.");
3063 return false;
3064 }
3065
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)3066 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
3067 {
3068 SessionInfo sessionInfo;
3069 if (property == nullptr) {
3070 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3071 return sessionInfo;
3072 }
3073 sessionInfo = property->GetSessionInfo();
3074 sessionInfo.persistentId_ = property->GetPersistentId();
3075 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
3076 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
3077 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
3078 sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
3079 ? SessionState::STATE_ACTIVE
3080 : SessionState::STATE_BACKGROUND;
3081 sessionInfo.isPersistentRecover_ = true;
3082 TLOGI(WmsLogTag::WMS_RECOVER,
3083 "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
3084 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
3085 "windowState=%{public}u",
3086 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
3087 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_);
3088 return sessionInfo;
3089 }
3090
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)3091 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
3092 {
3093 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
3094 "%{public}d", alivePersistentIds.size(), currentUserId_.load());
3095 alivePersistentIds_ = alivePersistentIds;
3096 }
3097
IsNeedRecover(const int32_t persistentId)3098 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
3099 {
3100 auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
3101 if (it == alivePersistentIds_.end()) {
3102 TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
3103 return false;
3104 }
3105 return true;
3106 }
3107
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)3108 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
3109 bool isSpecificSession)
3110 {
3111 if (property == nullptr) {
3112 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3113 return WSError::WS_ERROR_NULLPTR;
3114 }
3115 if (!CheckSystemWindowPermission(property)) {
3116 TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
3117 return WSError::WS_ERROR_NOT_SYSTEM_APP;
3118 }
3119 if (isSpecificSession) {
3120 if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
3121 return WSError::WS_ERROR_INVALID_PARAM;
3122 }
3123 } else {
3124 if (!IsNeedRecover(property->GetPersistentId())) {
3125 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
3126 return WSError::WS_ERROR_INVALID_PARAM;
3127 }
3128 }
3129 return WSError::WS_OK;
3130 }
3131
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)3132 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3133 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3134 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
3135 {
3136 auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
3137 if (propCheckRet != WSError::WS_OK) {
3138 return propCheckRet;
3139 }
3140 auto pid = IPCSkeleton::GetCallingRealPid();
3141 auto uid = IPCSkeleton::GetCallingUid();
3142 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
3143 if (recoveringFinished_) {
3144 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3145 return WSError::WS_ERROR_INVALID_OPERATION;
3146 }
3147 // recover specific session
3148 SessionInfo info = RecoverSessionInfo(property);
3149 TLOGI(WmsLogTag::WMS_RECOVER, "callingWindowId = %{public}" PRIu32, property->GetCallingSessionId());
3150 ClosePipWindowIfExist(property->GetWindowType());
3151 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
3152 if (sceneSession == nullptr) {
3153 TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
3154 return WSError::WS_ERROR_NULLPTR;
3155 }
3156
3157 auto persistentId = sceneSession->GetPersistentId();
3158 if (persistentId != info.persistentId_) {
3159 TLOGE(WmsLogTag::WMS_RECOVER,
3160 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
3161 info.persistentId_, persistentId, property->GetParentPersistentId());
3162 failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
3163 EraseSceneSessionMapById(persistentId);
3164 return WSError::WS_ERROR_INVALID_SESSION;
3165 }
3166
3167 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3168 if (errCode != WSError::WS_OK) {
3169 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
3170 EraseSceneSessionMapById(persistentId);
3171 return errCode;
3172 }
3173 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
3174 CacheSubSessionForRecovering(sceneSession, property);
3175 NotifySessionUnfocusedToClient(persistentId);
3176 AddClientDeathRecipient(sessionStage, sceneSession);
3177 session = sceneSession;
3178 return errCode;
3179 };
3180 return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
3181 }
3182
NotifyRecoveringFinished()3183 void SceneSessionManager::NotifyRecoveringFinished()
3184 {
3185 taskScheduler_->PostAsyncTask([this]() {
3186 TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
3187 recoveringFinished_ = true;
3188 recoverSubSessionCacheMap_.clear();
3189 }, "NotifyRecoveringFinished");
3190 }
3191
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)3192 void SceneSessionManager::CacheSubSessionForRecovering(
3193 sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
3194 {
3195 if (recoveringFinished_) {
3196 TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
3197 return;
3198 }
3199
3200 if (sceneSession == nullptr || property == nullptr) {
3201 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
3202 return;
3203 }
3204
3205 auto windowType = property->GetWindowType();
3206 if (!SessionHelper::IsSubWindow(windowType)) {
3207 return;
3208 }
3209
3210 auto persistentId = property->GetParentPersistentId();
3211 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
3212 return;
3213 }
3214
3215 TLOGI(WmsLogTag::WMS_RECOVER,
3216 "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
3217 sceneSession->GetPersistentId(), persistentId);
3218
3219 if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
3220 recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
3221 } else {
3222 recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
3223 }
3224 }
3225
RecoverCachedSubSession(int32_t persistentId)3226 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
3227 {
3228 auto iter = recoverSubSessionCacheMap_.find(persistentId);
3229 if (iter == recoverSubSessionCacheMap_.end()) {
3230 return;
3231 }
3232
3233 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3234 for (auto& sceneSession : iter->second) {
3235 NotifyCreateSubSession(persistentId, sceneSession);
3236 }
3237 recoverSubSessionCacheMap_.erase(iter);
3238 }
3239
NotifySessionUnfocusedToClient(int32_t persistentId)3240 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
3241 {
3242 if (listenerController_ != nullptr) {
3243 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3244 listenerController_->NotifySessionUnfocused(persistentId);
3245 }
3246 }
3247
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)3248 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
3249 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3250 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
3251 {
3252 auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
3253 if (propCheckRet != WSError::WS_OK) {
3254 return propCheckRet;
3255 }
3256 auto pid = IPCSkeleton::GetCallingRealPid();
3257 auto uid = IPCSkeleton::GetCallingUid();
3258 auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
3259 if (recoveringFinished_) {
3260 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3261 return WSError::WS_ERROR_INVALID_OPERATION;
3262 }
3263 if (recoverSceneSessionFunc_ == nullptr) {
3264 TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
3265 return WSError::WS_ERROR_NULLPTR;
3266 }
3267 SessionInfo sessionInfo = RecoverSessionInfo(property);
3268 sptr<SceneSession> sceneSession = nullptr;
3269 if (SessionHelper::IsMainWindow(property->GetWindowType())) {
3270 sceneSession = RequestSceneSession(sessionInfo, nullptr);
3271 } else {
3272 sceneSession = RequestSceneSession(sessionInfo, property);
3273 }
3274 if (sceneSession == nullptr) {
3275 TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
3276 return WSError::WS_ERROR_NULLPTR;
3277 }
3278 int32_t persistentId = sceneSession->GetPersistentId();
3279 if (persistentId != sessionInfo.persistentId_) {
3280 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
3281 sessionInfo.persistentId_, persistentId);
3282 EraseSceneSessionMapById(persistentId);
3283 return WSError::WS_ERROR_INVALID_SESSION;
3284 }
3285 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3286 if (ret != WSError::WS_OK) {
3287 TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
3288 EraseSceneSessionMapById(sessionInfo.persistentId_);
3289 return ret;
3290 }
3291 sceneSession->SetRecovered(true);
3292 recoverSceneSessionFunc_(sceneSession, sessionInfo);
3293 NotifySessionUnfocusedToClient(persistentId);
3294 session = sceneSession;
3295 return WSError::WS_OK;
3296 };
3297 return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
3298 }
3299
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)3300 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
3301 {
3302 TLOGI(WmsLogTag::WMS_RECOVER, "called");
3303 recoverSceneSessionFunc_ = func;
3304 }
3305
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)3306 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
3307 {
3308 createSystemSessionFunc_ = func;
3309 }
3310
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)3311 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
3312 {
3313 createKeyboardSessionFunc_ = func;
3314 }
3315
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)3316 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
3317 {
3318 startPiPFailedFunc_ = std::move(func);
3319 }
3320
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)3321 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
3322 const NotifyCreateSubSessionFunc& func)
3323 {
3324 TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
3325 auto task = [this, persistentId, func]() {
3326 createSubSessionFuncMap_[persistentId] = func;
3327 RecoverCachedSubSession(persistentId);
3328 return WMError::WM_OK;
3329 };
3330 taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
3331 }
3332
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)3333 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
3334 sptr<WindowSessionProperty> property, const WindowType& type)
3335 {
3336 if (newSession == nullptr) {
3337 WLOGFE("newSession is nullptr");
3338 return;
3339 }
3340 if (property == nullptr) {
3341 WLOGFE("property is nullptr");
3342 return;
3343 }
3344 if (SessionHelper::IsSystemWindow(type)) {
3345 if (type == WindowType::WINDOW_TYPE_FLOAT) {
3346 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3347 if (parentSession != nullptr) {
3348 newSession->SetParentSession(parentSession);
3349 }
3350 }
3351 if (type == WindowType::WINDOW_TYPE_TOAST) {
3352 NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
3353 }
3354 if (type != WindowType::WINDOW_TYPE_DIALOG) {
3355 if (WindowHelper::IsSystemSubWindow(type)) {
3356 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3357 } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
3358 && createKeyboardSessionFunc_) {
3359 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
3360 } else if (createSystemSessionFunc_) {
3361 createSystemSessionFunc_(newSession);
3362 }
3363 TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
3364 newSession->GetPersistentId(), type);
3365 } else {
3366 TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, \
3367 type:%{public}d", newSession->GetPersistentId(), type);
3368 return;
3369 }
3370 } else if (SessionHelper::IsSubWindow(type)) {
3371 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3372 TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
3373 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
3374 } else {
3375 TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
3376 newSession->GetPersistentId(), type);
3377 }
3378 }
3379
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)3380 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
3381 {
3382 if (session == nullptr) {
3383 TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
3384 return;
3385 }
3386 auto iter = createSubSessionFuncMap_.find(persistentId);
3387 if (iter == createSubSessionFuncMap_.end()) {
3388 TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
3389 return;
3390 }
3391
3392 sptr<SceneSession> parentSession = nullptr;
3393 if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
3394 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3395 parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
3396 } else {
3397 parentSession = GetSceneSession(persistentId);
3398 }
3399 if (parentSession == nullptr) {
3400 TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
3401 persistentId, session->GetPersistentId());
3402 return;
3403 }
3404 parentSession->AddSubSession(session);
3405 session->SetParentSession(parentSession);
3406 if (iter->second) {
3407 iter->second(session);
3408 }
3409 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
3410 persistentId, session->GetPersistentId());
3411 }
3412
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)3413 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
3414 const std::map<int32_t, sptr<SceneSession>>& sessionMap)
3415 {
3416 if (persistentId == INVALID_SESSION_ID) {
3417 TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
3418 return nullptr;
3419 }
3420 auto iter = sessionMap.find(persistentId);
3421 if (iter == sessionMap.end()) {
3422 WLOGFD("Error found scene session with id: %{public}d", persistentId);
3423 return nullptr;
3424 }
3425 sptr<SceneSession> parentSession = iter->second;
3426 if (parentSession == nullptr) {
3427 TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
3428 return nullptr;
3429 }
3430 bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
3431 parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
3432 if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
3433 TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
3434 return parentSession;
3435 }
3436 return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
3437 }
3438
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)3439 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
3440 {
3441 if (session == nullptr) {
3442 TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
3443 return;
3444 }
3445
3446 auto parentSession = GetSceneSession(persistentId);
3447 if (parentSession == nullptr) {
3448 TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
3449 persistentId, session->GetPersistentId());
3450 return;
3451 }
3452 parentSession->AddToastSession(session);
3453 session->SetParentSession(parentSession);
3454 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
3455 persistentId, session->GetPersistentId());
3456 }
3457
UnregisterCreateSubSessionListener(int32_t persistentId)3458 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
3459 {
3460 TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
3461 auto task = [this, persistentId]() {
3462 auto iter = createSubSessionFuncMap_.find(persistentId);
3463 if (iter != createSubSessionFuncMap_.end()) {
3464 createSubSessionFuncMap_.erase(persistentId);
3465 } else {
3466 TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
3467 }
3468 return WMError::WM_OK;
3469 };
3470 taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
3471 }
3472
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)3473 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
3474 {
3475 WLOGFD("SetStatusBarEnabledChangeListener");
3476 if (!func) {
3477 WLOGFD("set func is null");
3478 }
3479 statusBarEnabledChangeFunc_ = func;
3480 }
3481
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)3482 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
3483 const ProcessGestureNavigationEnabledChangeFunc& func)
3484 {
3485 WLOGFD("SetGestureNavigationEnabledChangeListener");
3486 if (!func) {
3487 WLOGFD("set func is null");
3488 }
3489 gestureNavigationEnabledChangeFunc_ = func;
3490 }
3491
OnOutsideDownEvent(int32_t x,int32_t y)3492 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
3493 {
3494 TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
3495 if (outsideDownEventFunc_) {
3496 outsideDownEventFunc_(x, y);
3497 }
3498 }
3499
NotifySessionTouchOutside(int32_t persistentId)3500 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
3501 {
3502 auto task = [this, persistentId]() {
3503 int32_t callingSessionId = INVALID_SESSION_ID;
3504 auto sceneSession = GetSceneSession(persistentId);
3505 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3506 callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
3507 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
3508 persistentId, callingSessionId);
3509 }
3510 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3511 for (const auto &item : sceneSessionMap_) {
3512 sceneSession = item.second;
3513 if (sceneSession == nullptr) {
3514 continue;
3515 }
3516 if (!(sceneSession->IsVisible() ||
3517 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3518 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
3519 continue;
3520 }
3521 auto sessionId = sceneSession->GetPersistentId();
3522 if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
3523 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3524 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3525 continue;
3526 }
3527 if (sessionId == callingSessionId || sessionId == persistentId) {
3528 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3529 continue;
3530 }
3531 sceneSession->NotifyTouchOutside();
3532 }
3533 };
3534
3535 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3536 return;
3537 }
3538
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)3539 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3540 {
3541 WLOGFD("SetOutsideDownEventListener");
3542 outsideDownEventFunc_ = func;
3543 }
3544
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)3545 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
3546 {
3547 for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
3548 if (iter->second != persistentId) {
3549 continue;
3550 }
3551 if (windowDeath_ == nullptr) {
3552 TLOGE(WmsLogTag::WMS_LIFE, "death recipient is null");
3553 } else {
3554 if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
3555 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
3556 }
3557 }
3558 remoteObjectMap_.erase(iter);
3559 break;
3560 }
3561 }
3562
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3563 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3564 {
3565 auto sceneSession = GetSceneSession(persistentId);
3566 if (sceneSession == nullptr) {
3567 return WSError::WS_ERROR_NULLPTR;
3568 }
3569 auto ret = sceneSession->UpdateActiveStatus(false);
3570 WindowDestroyNotifyVisibility(sceneSession);
3571 auto windowType = sceneSession->GetWindowType();
3572 if (windowType == WindowType::WINDOW_TYPE_DIALOG) {
3573 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3574 if (parentSession == nullptr) {
3575 TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3576 } else {
3577 parentSession->RemoveDialogToParentSession(sceneSession);
3578 }
3579 } else if (windowType == WindowType::WINDOW_TYPE_TOAST) {
3580 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3581 if (parentSession != nullptr) {
3582 TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3583 parentSession->RemoveToastSession(persistentId);
3584 } else {
3585 TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3586 }
3587 } else if (windowType == WindowType::WINDOW_TYPE_FLOAT) {
3588 DestroySubSession(sceneSession);
3589 }
3590 ret = sceneSession->Disconnect();
3591 sceneSession->ClearSpecificSessionCbMap();
3592 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3593 DestroySubSession(sceneSession);
3594 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3595 if (parentSession != nullptr) {
3596 TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3597 parentSession->RemoveSubSession(sceneSession->GetPersistentId());
3598 } else {
3599 TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3600 }
3601 DestroyUIServiceExtensionSubWindow(sceneSession);
3602 }
3603 {
3604 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3605 EraseSceneSessionAndMarkDirtyLocked(persistentId);
3606 systemTopSceneSessionMap_.erase(persistentId);
3607 nonSystemFloatSceneSessionMap_.erase(persistentId);
3608 UnregisterCreateSubSessionListener(persistentId);
3609 }
3610 ClearSpecificSessionRemoteObjectMap(persistentId);
3611 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3612 return ret;
3613 }
3614
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)3615 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
3616 {
3617 if (!sceneSession) {
3618 TLOGE(WmsLogTag::WMS_SUB,"sceneSession is null");
3619 return;
3620 }
3621 auto sessionProperty = sceneSession->GetSessionProperty();
3622 if (sessionProperty && sessionProperty->GetExtensionFlag() == true &&
3623 !sessionProperty->GetIsUIExtensionAbilityProcess()) {
3624 sceneSession->NotifyDestroy();
3625 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
3626 TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
3627 TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
3628 sceneSession->GetPersistentId(), errCode);
3629 }
3630 }
3631
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3632 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3633 {
3634 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3635 auto task = [this, persistentId, callingPid]() {
3636 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3637 auto sceneSession = GetSceneSession(persistentId);
3638 if (sceneSession == nullptr) {
3639 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3640 return WSError::WS_ERROR_NULLPTR;
3641 }
3642
3643 if (callingPid != sceneSession->GetCallingPid()) {
3644 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3645 return WSError::WS_ERROR_INVALID_PERMISSION;
3646 }
3647 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3648 };
3649
3650 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3651 }
3652
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)3653 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3654 const sptr<IRemoteObject>& callback)
3655 {
3656 if (callback == nullptr) {
3657 return WSError::WS_ERROR_NULLPTR;
3658 }
3659 const auto callingPid = IPCSkeleton::GetCallingRealPid();
3660 auto task = [this, persistentId, callingPid, callback]() {
3661 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3662 auto sceneSession = GetSceneSession(persistentId);
3663 if (sceneSession == nullptr) {
3664 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3665 return WSError::WS_ERROR_NULLPTR;
3666 }
3667
3668 if (callingPid != sceneSession->GetCallingPid()) {
3669 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3670 return WSError::WS_ERROR_INVALID_PERMISSION;
3671 }
3672 sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3673 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3674 };
3675
3676 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3677 }
3678
GetWindowSceneConfig() const3679 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3680 {
3681 return appWindowSceneConfig_;
3682 }
3683
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)3684 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3685 {
3686 auto task = [this, config]() {
3687 TLOGI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3688 rotateAnimationConfig_.duration_ = config.duration_;
3689 };
3690 taskScheduler_->PostAsyncTask(task, "UpdateRotateAnimationConfig");
3691 }
3692
ProcessBackEvent()3693 WSError SceneSessionManager::ProcessBackEvent()
3694 {
3695 auto task = [this]() {
3696 auto session = GetSceneSession(focusedSessionId_);
3697 if (!session) {
3698 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId_);
3699 return WSError::WS_ERROR_INVALID_SESSION;
3700 }
3701 TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
3702 focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3703 if (needBlockNotifyFocusStatusUntilForeground_ || !session->IsSessionValid()) {
3704 TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
3705 if (session->GetSessionInfo().abilityInfo != nullptr &&
3706 session->GetSessionInfo().abilityInfo->unclearableMission) {
3707 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3708 return WSError::WS_OK;
3709 }
3710 session->RequestSessionBack(true);
3711 return WSError::WS_OK;
3712 }
3713 if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3714 rootSceneProcessBackEventFunc_();
3715 } else {
3716 session->ProcessBackEvent();
3717 }
3718 return WSError::WS_OK;
3719 };
3720
3721 taskScheduler_->PostAsyncTask(task, __func__);
3722 return WSError::WS_OK;
3723 }
3724
InitUserInfo(int32_t userId,std::string & fileDir)3725 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3726 {
3727 if (userId == DEFAULT_USERID || fileDir.empty()) {
3728 TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3729 return WSError::WS_DO_NOTHING;
3730 }
3731 TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3732 auto task = [this, userId, &fileDir]() {
3733 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3734 TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3735 }
3736 if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3737 TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3738 }
3739 currentUserId_ = userId;
3740 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3741 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3742 RegisterSecSurfaceInfoListener();
3743 RegisterConstrainedModalUIExtInfoListener();
3744 return WSError::WS_OK;
3745 };
3746 return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3747 }
3748
NotifySwitchingUser(const bool isUserActive)3749 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3750 {
3751 auto task = [this, isUserActive]() {
3752 TLOGI(WmsLogTag::WMS_MULTI_USER, "Notify switching user. IsUserActive=%{public}u, currentUserId=%{public}d",
3753 isUserActive, currentUserId_.load());
3754 isUserBackground_ = !isUserActive;
3755 SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3756 if (isUserActive) { // switch to current user
3757 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3758 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3759 // notify screenSessionManager to recover current user
3760 ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3761 FlushWindowInfoToMMI(true);
3762 NotifyAllAccessibilityInfo();
3763 rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3764 UpdatePrivateStateAndNotifyForAllScreens();
3765 } else { // switch to another user
3766 SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3767 rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3768 }
3769 return WSError::WS_OK;
3770 };
3771 taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3772 }
3773
GetBundleManager()3774 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3775 {
3776 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3777 if (systemAbilityMgr == nullptr) {
3778 WLOGFE("Failed to get SystemAbilityManager.");
3779 return nullptr;
3780 }
3781
3782 auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3783 if (bmsObj == nullptr) {
3784 WLOGFE("Failed to get BundleManagerService.");
3785 return nullptr;
3786 }
3787
3788 return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3789 }
3790
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)3791 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3792 const AppExecFwk::AbilityInfo& abilityInfo)
3793 {
3794 auto context = rootSceneContextWeak_.lock();
3795 if (!context) {
3796 WLOGFE("context is nullptr.");
3797 return nullptr;
3798 }
3799 auto resourceMgr = context->GetResourceManager();
3800 if (!resourceMgr) {
3801 WLOGFE("resourceMgr is nullptr.");
3802 return nullptr;
3803 }
3804 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3805 if (!resConfig) {
3806 WLOGFE("resConfig is nullptr.");
3807 return nullptr;
3808 }
3809 resourceMgr->GetResConfig(*resConfig);
3810 resourceMgr = Global::Resource::CreateResourceManager(
3811 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3812 if (!resourceMgr) {
3813 WLOGFE("resourceMgr is nullptr.");
3814 return nullptr;
3815 }
3816 resourceMgr->UpdateResConfig(*resConfig);
3817
3818 std::string loadPath;
3819 if (!abilityInfo.hapPath.empty()) { // zipped hap
3820 loadPath = abilityInfo.hapPath;
3821 } else {
3822 loadPath = abilityInfo.resourcePath;
3823 }
3824
3825 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3826 WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3827 }
3828 return resourceMgr;
3829 }
3830
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)3831 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3832 std::string& path, uint32_t& bgColor)
3833 {
3834 auto resourceMgr = GetResourceManager(abilityInfo);
3835 if (!resourceMgr) {
3836 WLOGFE("resourceMgr is nullptr.");
3837 return false;
3838 }
3839
3840 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3841 WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3842 return false;
3843 }
3844
3845 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3846 WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3847 return false;
3848 }
3849
3850 if (!abilityInfo.hapPath.empty()) { // zipped hap
3851 auto pos = path.find_last_of('.');
3852 if (pos == std::string::npos) {
3853 WLOGFE("Format error, path %{private}s.", path.c_str());
3854 return false;
3855 }
3856 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3857 }
3858 return true;
3859 }
3860
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3861 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3862 {
3863 if (!bundleMgr_) {
3864 WLOGFE("bundleMgr_ is nullptr.");
3865 return;
3866 }
3867 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3868 if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3869 WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3870 return;
3871 }
3872 AAFwk::Want want;
3873 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3874 AppExecFwk::AbilityInfo abilityInfo;
3875 if (!bundleMgr_->QueryAbilityInfo(
3876 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3877 WLOGFE("Get ability info from BMS failed!");
3878 return;
3879 }
3880
3881 if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3882 CacheStartingWindowInfo(abilityInfo, path, bgColor);
3883 }
3884 WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3885 abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3886 }
3887
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3888 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3889 const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3890 {
3891 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3892 std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3893 auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3894 if (iter == startingWindowMap_.end()) {
3895 return false;
3896 }
3897 auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3898 const auto& infoMap = iter->second;
3899 auto infoMapIter = infoMap.find(key);
3900 if (infoMapIter == infoMap.end()) {
3901 return false;
3902 }
3903 path = infoMapIter->second.startingWindowIconPath_;
3904 bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3905 return true;
3906 }
3907
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)3908 void SceneSessionManager::CacheStartingWindowInfo(
3909 const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3910 {
3911 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3912 auto key = abilityInfo.moduleName + abilityInfo.name;
3913 StartingWindowInfo info = {
3914 .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3915 .startingWindowIconId_ = abilityInfo.startWindowIconId,
3916 .startingWindowBackgroundColor_ = bgColor,
3917 .startingWindowIconPath_ = path,
3918 };
3919 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3920 auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3921 if (iter != startingWindowMap_.end()) {
3922 auto& infoMap = iter->second;
3923 infoMap.emplace(key, info);
3924 return;
3925 }
3926 if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3927 startingWindowMap_.erase(startingWindowMap_.begin());
3928 }
3929 std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3930 startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3931 }
3932
OnBundleUpdated(const std::string & bundleName,int userId)3933 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3934 {
3935 taskScheduler_->PostAsyncTask([this, bundleName]() {
3936 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3937 auto iter = startingWindowMap_.find(bundleName);
3938 if (iter != startingWindowMap_.end()) {
3939 startingWindowMap_.erase(iter);
3940 }
3941 },
3942 "OnBundleUpdated");
3943 }
3944
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3945 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3946 {
3947 taskScheduler_->PostAsyncTask([this]() {
3948 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3949 startingWindowMap_.clear();
3950 },
3951 "OnConfigurationUpdated");
3952 }
3953
FillSessionInfo(sptr<SceneSession> & sceneSession)3954 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3955 {
3956 auto sessionInfo = sceneSession->GetSessionInfo();
3957 if (sessionInfo.bundleName_.empty()) {
3958 WLOGFE("bundleName_ is empty");
3959 return;
3960 }
3961 if (sessionInfo.isSystem_) {
3962 WLOGFD("is system scene!");
3963 return;
3964 }
3965 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3966 sessionInfo.moduleName_);
3967 if (abilityInfo == nullptr) {
3968 WLOGFE("abilityInfo is nullptr!");
3969 return;
3970 }
3971 sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
3972 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3973 sceneSession->SetSessionInfoTime(GetCurrentTime());
3974 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3975 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3976 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3977 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3978 }
3979 TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3980 "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3981 abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3982 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3983 }
3984
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)3985 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3986 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3987 {
3988 if (!bundleMgr_) {
3989 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3990 return nullptr;
3991 }
3992 AAFwk::Want want;
3993 want.SetElementName("", bundleName, abilityName, moduleName);
3994 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3995 if (abilityInfo == nullptr) {
3996 WLOGFE("abilityInfo is nullptr!");
3997 return nullptr;
3998 }
3999 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
4000 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
4001 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
4002 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
4003 if (!ret) {
4004 WLOGFE("Get ability info from BMS failed!");
4005 return nullptr;
4006 }
4007 return abilityInfo;
4008 }
4009
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)4010 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
4011 uint32_t& topWinId, uint32_t& zOrder)
4012 {
4013 const auto& subVec = session->GetSubSession();
4014 for (const auto& subSession : subVec) {
4015 if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
4016 TLOGW(WmsLogTag::WMS_SUB,
4017 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
4018 continue;
4019 }
4020 if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4021 subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
4022 subSession->GetZOrder() > zOrder) {
4023 topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
4024 zOrder = subSession->GetZOrder();
4025 TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
4026 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
4027 }
4028 if (subSession->GetSubSession().size() > 0) {
4029 GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
4030 }
4031 }
4032 }
4033
4034 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)4035 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
4036 {
4037 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4038 auto task = [this, mainWinId, &topWinId, callingPid]() {
4039 const auto& mainSession = GetSceneSession(mainWinId);
4040 if (mainSession == nullptr) {
4041 return WMError::WM_ERROR_INVALID_WINDOW;
4042 }
4043
4044 if (callingPid != mainSession->GetCallingPid()) {
4045 WLOGFE("Permission denied, not destroy by the same process");
4046 return WMError::WM_ERROR_INVALID_PERMISSION;
4047 }
4048 uint32_t zOrder = mainSession->GetZOrder();
4049 topWinId = mainWinId;
4050 GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
4051 TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
4052 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
4053 return WMError::WM_OK;
4054 };
4055
4056 if (!Session::IsScbCoreEnabled()) {
4057 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4058 }
4059 bool postNow = false;
4060 auto mainSession = GetSceneSession(mainWinId);
4061 if (mainSession != nullptr) {
4062 postNow = !(mainSession->GetUIStateDirty());
4063 }
4064 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
4065 if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
4066 taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
4067 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4068 }
4069 TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
4070 {
4071 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
4072 if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
4073 std::cv_status::timeout) {
4074 TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
4075 }
4076 }
4077 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4078 }
4079
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)4080 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
4081 int32_t windowId, int32_t& mainWindowId)
4082 {
4083 auto iter = sceneSessionMap.find(windowId);
4084 if (iter == sceneSessionMap.end()) {
4085 TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
4086 return WMError::WM_ERROR_NULLPTR;
4087 }
4088 sptr<SceneSession> sceneSession = iter->second;
4089 if (sceneSession == nullptr) {
4090 TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
4091 return WMError::WM_ERROR_NULLPTR;
4092 }
4093 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
4094 mainWindowId = sceneSession->GetPersistentId();
4095 return WMError::WM_OK;
4096 }
4097 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4098 WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
4099 return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
4100 }
4101 // not sub window, dialog, return invalid id
4102 mainWindowId = INVALID_SESSION_ID;
4103 return WMError::WM_OK;
4104 }
4105
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)4106 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
4107 {
4108 if (windowId == INVALID_SESSION_ID) {
4109 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
4110 return WMError::WM_ERROR_INVALID_PARAM;
4111 }
4112 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4113 return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
4114 }
4115
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4116 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
4117 const sptr<SceneSession>& sceneSession)
4118 {
4119 auto systemBarProperties = property->GetSystemBarProperty();
4120 for (auto iter : systemBarProperties) {
4121 if (iter.first == type) {
4122 sceneSession->SetSystemBarProperty(iter.first, iter.second);
4123 TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
4124 static_cast<int32_t>(iter.first), iter.second.enable_);
4125 }
4126 }
4127 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4128 }
4129
4130 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4131 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
4132 const sptr<SceneSession>& sceneSession)
4133 {
4134 if (!SessionPermission::IsSystemCalling()) {
4135 TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
4136 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4137 }
4138
4139 sceneSession->SetTopmost(property->IsTopmost());
4140 return WMError::WM_OK;
4141 }
4142
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4143 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
4144 const sptr<SceneSession>& sceneSession)
4145 {
4146 bool isPcWindow = false;
4147 IsPcWindow(isPcWindow);
4148 if (isPcWindow) {
4149 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
4150 return;
4151 }
4152 auto propertyOld = sceneSession->GetSessionProperty();
4153 if (propertyOld == nullptr) {
4154 TLOGI(WmsLogTag::DEFAULT, "session property null");
4155 return;
4156 }
4157
4158 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
4159 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
4160 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
4161 TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
4162 return;
4163 }
4164
4165 if (IsSessionVisibleForeground(sceneSession)) {
4166 if (hideNonSystemFloatingWindowsOld) {
4167 UpdateForceHideState(sceneSession, propertyOld, false);
4168 } else {
4169 UpdateForceHideState(sceneSession, property, true);
4170 }
4171 }
4172 }
4173
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)4174 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
4175 const sptr<WindowSessionProperty>& property, bool add)
4176 {
4177 if (systemConfig_.uiType_ == UI_TYPE_PC) {
4178 TLOGI(WmsLogTag::DEFAULT, "IsPcWindow, ineffective");
4179 return;
4180 }
4181 if (property == nullptr) {
4182 WLOGFD("property is nullptr");
4183 return;
4184 }
4185 auto persistentId = sceneSession->GetPersistentId();
4186 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
4187 bool notifyAll = false;
4188 if (add) {
4189 if (property->GetHideNonSystemFloatingWindows()) {
4190 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
4191 notifyAll = !forceHideFloatOld;
4192 } else if (property->IsFloatingWindowAppType()) {
4193 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
4194 if (forceHideFloatOld) {
4195 sceneSession->NotifyForceHideChange(true);
4196 }
4197 }
4198 } else {
4199 if (property->GetHideNonSystemFloatingWindows()) {
4200 systemTopSceneSessionMap_.erase(persistentId);
4201 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
4202 } else if (property->IsFloatingWindowAppType()) {
4203 nonSystemFloatSceneSessionMap_.erase(persistentId);
4204 if (property->GetForceHide()) {
4205 sceneSession->NotifyForceHideChange(false);
4206 }
4207 }
4208 }
4209 if (notifyAll) {
4210 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
4211 for (const auto& item : nonSystemFloatSceneSessionMap_) {
4212 auto forceHideSceneSession = item.second;
4213 auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
4214 if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
4215 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
4216 }
4217 }
4218 }
4219 }
4220
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)4221 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
4222 {
4223 #ifdef POWER_MANAGER_ENABLE
4224 auto task = [this, sceneSession]() {
4225 if (sceneSession == nullptr) {
4226 WLOGFE("session is invalid");
4227 return;
4228 }
4229 WLOGFD("Win: %{public}s, is turn on%{public}d",
4230 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4231 std::string identity = IPCSkeleton::ResetCallingIdentity();
4232 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
4233 WLOGI("turn screen on");
4234 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4235 }
4236 // set ipc identity to raw
4237 IPCSkeleton::SetCallingIdentity(identity);
4238 };
4239 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
4240
4241 #else
4242 WLOGFD("Can not found the sub system of PowerMgr");
4243 #endif
4244 }
4245
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)4246 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
4247 {
4248 #ifdef POWER_MANAGER_ENABLE
4249 wptr<SceneSession> weakSceneSession(sceneSession);
4250 auto task = [this, weakSceneSession, requireLock]() {
4251 auto scnSession = weakSceneSession.promote();
4252 if (scnSession == nullptr) {
4253 WLOGFE("session is invalid");
4254 return;
4255 }
4256 if (requireLock && scnSession->keepScreenLock_ == nullptr) {
4257 // reset ipc identity
4258 std::string identity = IPCSkeleton::ResetCallingIdentity();
4259 scnSession->keepScreenLock_ =
4260 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
4261 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
4262 // set ipc identity to raw
4263 IPCSkeleton::SetCallingIdentity(identity);
4264 }
4265 if (scnSession->keepScreenLock_ == nullptr) {
4266 return;
4267 }
4268 auto curScreenId = scnSession->GetSessionInfo().screenId_;
4269 auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
4270 if (auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(curScreenId)) {
4271 sourceMode = screenSession->GetSourceMode();
4272 }
4273 bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession) && sourceMode != ScreenSourceMode::SCREEN_UNIQUE;
4274 TLOGNI(WmsLogTag::WMS_ATTRIBUTE,
4275 "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d]",
4276 scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
4277 scnSession->IsVisible(), requireLock, shouldLock, curScreenId, sourceMode);
4278 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
4279 ErrCode res;
4280 std::string identity = IPCSkeleton::ResetCallingIdentity();
4281 if (shouldLock) {
4282 res = scnSession->keepScreenLock_->Lock();
4283 } else {
4284 res = scnSession->keepScreenLock_->UnLock();
4285 }
4286 // set ipc identity to raw
4287 IPCSkeleton::SetCallingIdentity(identity);
4288 if (res != ERR_OK) {
4289 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
4290 requireLock, res);
4291 }
4292 };
4293 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
4294 #else
4295 WLOGFD("Can not found the sub system of PowerMgr");
4296 #endif
4297 }
4298
NotifyVisibleChange(int32_t persistentId)4299 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
4300 {
4301 auto sceneSession = GetSceneSession(persistentId);
4302 if (sceneSession == nullptr) {
4303 return false;
4304 }
4305 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
4306 ProcessWindowModeType();
4307 return true;
4308 }
4309
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)4310 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
4311 {
4312 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
4313 if (GetDisplayBrightness() != brightness &&
4314 GetFocusedSessionId() == sceneSession->GetPersistentId()) {
4315 PostBrightnessTask(brightness);
4316 }
4317 #else
4318 WLOGFD("Can not found the sub system of DisplayPowerMgr");
4319 #endif
4320 brightnessSessionId_ = sceneSession->GetPersistentId();
4321 return WSError::WS_OK;
4322 }
4323
PostBrightnessTask(float brightness)4324 void SceneSessionManager::PostBrightnessTask(float brightness)
4325 {
4326 bool postTaskRet = true;
4327 bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4328 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4329 if (!isPC) {
4330 auto task = [] {
4331 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4332 };
4333 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
4334 }
4335 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4336 } else {
4337 auto task = [brightness, isPC] {
4338 if (isPC) {
4339 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4340 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4341 } else {
4342 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4343 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4344 }
4345 };
4346 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
4347 SetDisplayBrightness(brightness);
4348 }
4349 if (!postTaskRet) {
4350 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
4351 }
4352 }
4353
UpdateBrightness(int32_t persistentId)4354 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
4355 {
4356 auto sceneSession = GetSceneSession(persistentId);
4357 if (sceneSession == nullptr) {
4358 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4359 return WSError::WS_ERROR_NULLPTR;
4360 }
4361 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4362 sceneSession->GetSessionInfo().isSystem_)) {
4363 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
4364 return WSError::WS_DO_NOTHING;
4365 }
4366 auto brightness = sceneSession->GetBrightness();
4367 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
4368 bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4369 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4370 if (GetDisplayBrightness() != brightness) {
4371 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
4372 if (!isPC) {
4373 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4374 }
4375 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4376 }
4377 brightnessSessionId_ = INVALID_WINDOW_ID;
4378 } else {
4379 if (GetDisplayBrightness() != brightness) {
4380 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
4381 if (isPC) {
4382 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4383 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4384 } else {
4385 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4386 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4387 }
4388 SetDisplayBrightness(brightness);
4389 }
4390 brightnessSessionId_ = sceneSession->GetPersistentId();
4391 }
4392 return WSError::WS_OK;
4393 }
4394
GetCurrentUserId() const4395 int32_t SceneSessionManager::GetCurrentUserId() const
4396 {
4397 return currentUserId_;
4398 }
4399
SetDisplayBrightness(float brightness)4400 void SceneSessionManager::SetDisplayBrightness(float brightness)
4401 {
4402 displayBrightness_ = brightness;
4403 }
4404
GetDisplayBrightness() const4405 float SceneSessionManager::GetDisplayBrightness() const
4406 {
4407 return displayBrightness_;
4408 }
4409
SetGestureNavigaionEnabled(bool enable)4410 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
4411 {
4412 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4413 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
4414 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4415 }
4416 std::string callerBundleName = SessionPermission::GetCallingBundleName();
4417 TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
4418 auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
4419 SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
4420 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
4421 WLOGFE("callback func is null");
4422 return WMError::WM_OK;
4423 }
4424 if (gestureNavigationEnabledChangeFunc_) {
4425 gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
4426 }
4427 if (statusBarEnabledChangeFunc_) {
4428 statusBarEnabledChangeFunc_(enable, bundleName);
4429 }
4430 return WMError::WM_OK;
4431 };
4432 return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
4433 }
4434
SetFocusedSessionId(int32_t persistentId)4435 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
4436 {
4437 if (focusedSessionId_ == persistentId) {
4438 WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
4439 return WSError::WS_DO_NOTHING;
4440 }
4441 lastFocusedSessionId_ = focusedSessionId_;
4442 focusedSessionId_ = persistentId;
4443 return WSError::WS_OK;
4444 }
4445
GetFocusedSessionId() const4446 int32_t SceneSessionManager::GetFocusedSessionId() const
4447 {
4448 return focusedSessionId_;
4449 }
4450
GetFocusWindowInfo(FocusChangeInfo & focusInfo)4451 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
4452 {
4453 if (!SessionPermission::IsSACalling()) {
4454 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
4455 return;
4456 }
4457 auto task = [this, &focusInfo] {
4458 if (auto sceneSession = GetSceneSession(focusedSessionId_)) {
4459 TLOGND(WmsLogTag::WMS_FOCUS, "Get focus session info success");
4460 focusInfo.windowId_ = sceneSession->GetWindowId();
4461 focusInfo.displayId_ = static_cast<DisplayId>(0);
4462 focusInfo.pid_ = sceneSession->GetCallingPid();
4463 focusInfo.uid_ = sceneSession->GetCallingUid();
4464 focusInfo.windowType_ = sceneSession->GetWindowType();
4465 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
4466 return WSError::WS_OK;
4467 }
4468 return WSError::WS_ERROR_DESTROYED_OBJECT;
4469 };
4470 taskScheduler_->PostSyncTask(task, __func__);
4471 }
4472
IsValidDigitString(const std::string & windowIdStr)4473 static bool IsValidDigitString(const std::string& windowIdStr)
4474 {
4475 if (windowIdStr.empty()) {
4476 return false;
4477 }
4478 for (char ch : windowIdStr) {
4479 if ((ch >= '0' && ch <= '9')) {
4480 continue;
4481 }
4482 WLOGFE("invalid window id");
4483 return false;
4484 }
4485 return true;
4486 }
4487
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)4488 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
4489 {
4490 if (sceneSession == nullptr) {
4491 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
4492 return;
4493 }
4494 const char* const where = __func__;
4495 sceneSession->SetSessionExceptionListener([this, where](
4496 const SessionInfo& info, bool needRemoveSession = false, bool startFail = false) {
4497 auto task = [this, info, where] {
4498 auto scnSession = GetSceneSession(info.persistentId_);
4499 if (scnSession == nullptr) {
4500 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
4501 return;
4502 }
4503 if (listenerController_ == nullptr) {
4504 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s listenerController_ is nullptr", where);
4505 return;
4506 }
4507 if (scnSession->GetSessionInfo().isSystem_) {
4508 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where,
4509 scnSession->GetPersistentId());
4510 return;
4511 }
4512 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
4513 where, info.errorCode, info.persistentId_);
4514 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
4515 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
4516 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
4517 "or foreground timeout, id: %{public}d", info.persistentId_);
4518 listenerController_->NotifySessionClosed(info.persistentId_);
4519 }
4520 };
4521 taskScheduler_->PostVoidSyncTask(task, "sessionException");
4522 }, false);
4523 TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
4524 }
4525
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)4526 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
4527 {
4528 if (sceneSession == nullptr) {
4529 WLOGFE("session is nullptr");
4530 return;
4531 }
4532 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
4533 auto sceneSession = GetSceneSession(persistentId);
4534 if (sceneSession == nullptr) {
4535 WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
4536 return;
4537 }
4538 if (sceneSession->GetSessionInfo().isSystem_) {
4539 WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
4540 return;
4541 }
4542 auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
4543 if (abilityInfoPtr == nullptr) {
4544 WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
4545 return;
4546 }
4547 if (listenerController_ == nullptr) {
4548 WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
4549 return;
4550 }
4551 if (!abilityInfoPtr->excludeFromMissions) {
4552 listenerController_->NotifySessionSnapshotChanged(persistentId);
4553 }
4554 };
4555 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
4556 WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
4557 }
4558
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)4559 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
4560 {
4561 if (sceneSession == nullptr) {
4562 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
4563 return;
4564 }
4565 AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
4566 config.duration_ = rotateAnimationConfig_.duration_;
4567 };
4568 sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
4569 TLOGD(WmsLogTag::DEFAULT, "Register acquire Rotate Animation config success, id: %{public}d",
4570 sceneSession->GetPersistentId());
4571 }
4572
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)4573 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
4574 {
4575 if (scnSession == nullptr) {
4576 WLOGFW("NotifySessionForCallback, scnSession is nullptr");
4577 return;
4578 }
4579 if (scnSession->GetSessionInfo().isSystem_) {
4580 WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
4581 return;
4582 }
4583 WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
4584 static_cast<uint32_t>(needRemoveSession));
4585 if (scnSession->GetSessionInfo().appIndex_ != 0) {
4586 WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
4587 scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
4588 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4589 return;
4590 }
4591 if (needRemoveSession) {
4592 WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
4593 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4594 return;
4595 }
4596 if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
4597 WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
4598 } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4599 (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4600 WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4601 scnSession->GetPersistentId());
4602 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4603 return;
4604 }
4605 WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
4606 listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
4607 }
4608
NotifyWindowInfoChangeFromSession(int32_t persistentId)4609 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4610 {
4611 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4612 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4613 if (sceneSession == nullptr) {
4614 WLOGFE("sceneSession nullptr");
4615 return;
4616 }
4617
4618 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4619 }
4620
IsSessionVisible(const sptr<SceneSession> & session)4621 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4622 {
4623 if (session == nullptr) {
4624 return false;
4625 }
4626 if (Session::IsScbCoreEnabled()) {
4627 return session->IsVisible();
4628 }
4629 const auto& state = session->GetSessionState();
4630 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4631 const auto& mainOrFloatSession = session->GetMainOrFloatSession();
4632 if (mainOrFloatSession == nullptr) {
4633 TLOGE(WmsLogTag::WMS_SUB, "Can not find parent for this sub window, id: %{public}d",
4634 session->GetPersistentId());
4635 return false;
4636 }
4637 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4638 const auto mainOrFloatSessionState = mainOrFloatSession->GetSessionState();
4639 if (mainOrFloatSessionState == SessionState::STATE_INACTIVE ||
4640 mainOrFloatSessionState == SessionState::STATE_BACKGROUND) {
4641 TLOGD(WmsLogTag::WMS_SUB, "Parent of this sub window is at background, id: %{public}d",
4642 session->GetPersistentId());
4643 return false;
4644 }
4645 WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4646 return true;
4647 }
4648 WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4649 return false;
4650 }
4651
4652 if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
4653 TLOGD(WmsLogTag::WMS_LIFE, "Window is at foreground, id: %{public}d", session->GetPersistentId());
4654 return true;
4655 }
4656 TLOGD(WmsLogTag::WMS_LIFE, "Window is at background, id: %{public}d", session->GetPersistentId());
4657 return false;
4658 }
4659
IsSessionVisibleForeground(const sptr<SceneSession> & session)4660 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4661 {
4662 if (session == nullptr) {
4663 return false;
4664 }
4665 if (Session::IsScbCoreEnabled()) {
4666 return session->IsVisibleForeground();
4667 }
4668 return IsSessionVisible(session);
4669 }
4670
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)4671 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4672 {
4673 if (session == nullptr) {
4674 return;
4675 }
4676 int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4677 WSRect rect = session->GetSessionRect();
4678 std::string sName;
4679 if (session->GetSessionInfo().isSystem_) {
4680 sName = session->GetSessionInfo().abilityName_;
4681 } else {
4682 sName = session->GetWindowName();
4683 }
4684 uint32_t flag = 0;
4685 uint64_t displayId = INVALID_SCREEN_ID;
4686 auto sessionProperty = session->GetSessionProperty();
4687 if (sessionProperty) {
4688 flag = sessionProperty->GetWindowFlags();
4689 displayId = sessionProperty->GetDisplayId();
4690 }
4691 uint32_t orientation = 0;
4692 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4693 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4694 // std::setw is used to set the output width and different width values are set to keep the format aligned.
4695 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4696 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4697 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4698 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4699 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4700 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4701 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4702 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4703 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4704 << "[ "
4705 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4706 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4707 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4708 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4709 << "]"
4710 << " [ "
4711 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4712 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4713 << "]"
4714 << " [ "
4715 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4716 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4717 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4718 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4719 << "]"
4720 << std::endl;
4721 }
4722
GetAllSessionDumpInfo(std::string & dumpInfo)4723 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4724 {
4725 std::ostringstream oss;
4726 oss << "-------------------------------------ScreenGroup 0"
4727 << "-------------------------------------" << std::endl;
4728 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
4729 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]" << std::endl;
4730 std::vector<sptr<SceneSession>> allSession;
4731 std::vector<sptr<SceneSession>> backgroundSession;
4732 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4733 {
4734 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4735 sceneSessionMapCopy = sceneSessionMap_;
4736 }
4737 for (const auto& elem : sceneSessionMapCopy) {
4738 auto curSession = elem.second;
4739 if (curSession == nullptr || (!curSession->GetSessionInfo().isSystem_ && (curSession->GetSessionState() <
4740 SessionState::STATE_FOREGROUND || curSession->GetSessionState() > SessionState::STATE_BACKGROUND))) {
4741 WLOGFW("Session is nullptr or session state is invalid, id: %{public}d, state: %{public}u",
4742 curSession->GetPersistentId(), curSession->GetSessionState());
4743 continue;
4744 }
4745 if (IsSessionVisibleForeground(curSession)) {
4746 allSession.push_back(curSession);
4747 } else {
4748 backgroundSession.push_back(curSession);
4749 }
4750 }
4751 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4752 uint32_t count = 0;
4753 for (const auto& session : allSession) {
4754 if (session == nullptr) {
4755 continue;
4756 }
4757 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4758 oss << "---------------------------------------------------------------------------------------"
4759 << std::endl;
4760 }
4761 DumpSessionInfo(session, oss);
4762 count++;
4763 }
4764 oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4765 oss << "SingleHand: X[" << singleHandTransform_.posX << "] Y[" << singleHandTransform_.posY << "] scale["
4766 << singleHandTransform_.scaleX << "]" << std::endl;
4767 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4768 oss << "Highlighted windows: " << GetHighlightIdsStr() << std::endl;
4769 dumpInfo.append(oss.str());
4770 return WSError::WS_OK;
4771 }
4772
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)4773 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4774 {
4775 dumpRootSceneFunc_ = func;
4776 }
4777
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)4778 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4779 const std::vector<std::string>& params, std::string& dumpInfo)
4780 {
4781 std::vector<std::string> resetParams;
4782 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4783 if (resetParams.empty()) {
4784 WLOGI("do not dump ui info");
4785 return;
4786 }
4787
4788 if (!session->GetSessionInfo().isSystem_) {
4789 WLOGFI("Dump normal session, not system");
4790 dumpInfoFuture_.ResetLock({});
4791 session->DumpSessionElementInfo(resetParams);
4792 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4793 for (auto& info: infos) {
4794 dumpInfo.append(info).append("\n");
4795 }
4796 } else {
4797 WLOGFI("Dump system session");
4798 std::vector<std::string> infos;
4799 dumpRootSceneFunc_(resetParams, infos);
4800 for (auto& info: infos) {
4801 dumpInfo.append(info).append("\n");
4802 }
4803 }
4804 }
4805
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)4806 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4807 const std::string& strId)
4808 {
4809 uint64_t persistentId = std::stoull(strId);
4810 auto session = GetSceneSession(persistentId);
4811 if (session == nullptr) {
4812 return WSError::WS_ERROR_INVALID_PARAM;
4813 }
4814 auto sessionProperty = session->GetSessionProperty();
4815 if (sessionProperty == nullptr) {
4816 return WSError::WS_ERROR_INVALID_PARAM;
4817 }
4818
4819 WSRect rect = session->GetSessionRect();
4820 std::string isVisible = session->IsVisible() ? "true" : "false";
4821 std::string focusable = session->GetFocusable() ? "true" : "false";
4822 std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4823 bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4824 std::string isPrivacyMode = privacyMode ? "true" : "false";
4825 bool isFirstFrameAvailable = true;
4826 std::ostringstream oss;
4827 oss << "WindowName: " << session->GetWindowName() << std::endl;
4828 oss << "DisplayId: " << 0 << std::endl;
4829 oss << "WinId: " << session->GetPersistentId() << std::endl;
4830 oss << "Pid: " << session->GetCallingPid() << std::endl;
4831 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4832 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4833 oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4834 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4835 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4836 oss << "IsVisible: " << isVisible << std::endl;
4837 oss << "Focusable: " << focusable << std::endl;
4838 oss << "DecoStatus: " << decoStatus << std::endl;
4839 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
4840 oss << "WindowRect: " << "[ "
4841 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4842 << " ]" << std::endl;
4843 oss << "scaleX: " << session->GetScaleX() << std::endl;
4844 oss << "scaleY: " << session->GetScaleY() << std::endl;
4845 oss << "Offset: " << "[ "
4846 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4847 oss << "Scale: " << "[ "
4848 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4849 << session->GetPivotX() << ", " << session->GetPivotY()
4850 << " ]" << std::endl;
4851 dumpInfo.append(oss.str());
4852
4853 DumpSessionElementInfo(session, params, dumpInfo);
4854 return WSError::WS_OK;
4855 }
4856
GetSCBDebugDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params)4857 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params)
4858 {
4859 std::string cmd = ScbDumpSubscriber::JoinCommands(params, params.size());
4860
4861 // publish data
4862 bool ret = eventHandler_->PostSyncTask([this, cmd] { return g_scbSubscriber->Publish(cmd); }, "PublishSCBDumper");
4863 if (!ret) {
4864 return WSError::WS_ERROR_INVALID_OPERATION;
4865 }
4866
4867 // get response event
4868 auto task = [this, &dumpInfo]() {
4869 dumpInfo.append(g_scbSubscriber->GetDebugDumpInfo(WAIT_TIME));
4870 return WSError::WS_OK;
4871 };
4872 eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4873
4874 return WSError::WS_OK;
4875 }
4876
NotifyDumpInfoResult(const std::vector<std::string> & info)4877 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4878 {
4879 dumpInfoFuture_.SetValue(info);
4880 WLOGFD("NotifyDumpInfoResult");
4881 }
4882
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)4883 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4884 {
4885 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4886 WLOGFE("GetSessionDumpInfo permission denied!");
4887 return WSError::WS_ERROR_INVALID_PERMISSION;
4888 }
4889
4890 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4891 return GetAllSessionDumpInfo(dumpInfo);
4892 }
4893 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4894 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4895 }
4896 if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2:params num
4897 return GetSCBDebugDumpInfo(dumpInfo, params);
4898 }
4899 if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
4900 return GetTotalUITreeInfo(dumpInfo);
4901 }
4902 return WSError::WS_ERROR_INVALID_OPERATION;
4903 }
4904
GetTotalUITreeInfo(std::string & dumpInfo)4905 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
4906 {
4907 TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4908 if (dumpUITreeFunc_) {
4909 dumpUITreeFunc_(dumpInfo);
4910 } else {
4911 TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4912 }
4913 return WSError::WS_OK;
4914 }
4915
SetDumpUITreeFunc(const DumpUITreeFunc & func)4916 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4917 {
4918 dumpUITreeFunc_ = func;
4919 }
4920
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)4921 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
4922 {
4923 onFlushUIParamsFunc_ = std::move(func);
4924 }
4925
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)4926 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
4927 {
4928 isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
4929 }
4930
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)4931 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
4932 {
4933 taskScheduler_->PostAsyncTask([this, displayId, visible] {
4934 statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
4935 TLOGNI(WmsLogTag::WMS_IMMS,
4936 "set default visibility on display: %{public}" PRIu64 " visible: %{public}d", displayId, visible);
4937 }, __func__);
4938 }
4939
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)4940 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
4941 {
4942 return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
4943 statusBarDefaultVisibilityPerDisplay_[displayId] : true;
4944 }
4945
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)4946 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4947 {
4948 // notify RS
4949 WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4950 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4951 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4952 sceneSession->GetSessionInfo().bundleName_.c_str(),
4953 sceneSession->GetSessionInfo().abilityName_.c_str(),
4954 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4955 uint64_t focusNodeId = 0; // 0 means invalid
4956 if (sceneSession->GetSurfaceNode() == nullptr) {
4957 WLOGFW("focused window surfaceNode is null");
4958 } else {
4959 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4960 }
4961 FocusAppInfo appInfo = {
4962 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4963 sceneSession->GetSessionInfo().bundleName_,
4964 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4965 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4966 }
4967
4968 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4969 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4970 {
4971 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4972 {
4973 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4974 for (auto& iter : sceneSessionMap_) {
4975 ret.push_back(iter);
4976 }
4977 }
4978 std::sort(ret.begin(), ret.end(), cmp);
4979 return ret;
4980 }
4981
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)4982 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4983 {
4984 if (isFromTopToBottom) {
4985 TraverseSessionTreeFromTopToBottom(func);
4986 } else {
4987 TraverseSessionTreeFromBottomToTop(func);
4988 }
4989 return;
4990 }
4991
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4992 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4993 {
4994 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4995 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4996 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4997 return lhsZOrder < rhsZOrder;
4998 };
4999 auto sceneSessionVector = GetSceneSessionVector(cmp);
5000
5001 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
5002 auto session = iter->second;
5003 if (session == nullptr) {
5004 WLOGFE("session is nullptr");
5005 continue;
5006 }
5007 if (func(session)) {
5008 return;
5009 }
5010 }
5011 return;
5012 }
5013
TraverseSessionTreeFromBottomToTop(TraverseFunc func)5014 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
5015 {
5016 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5017 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
5018 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
5019 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
5020 return lhsZOrder < rhsZOrder;
5021 };
5022 auto sceneSessionVector = GetSceneSessionVector(cmp);
5023 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
5024 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
5025 auto session = iter->second;
5026 if (session == nullptr) {
5027 WLOGFE("session is nullptr");
5028 continue;
5029 }
5030 if (func(session)) {
5031 return;
5032 }
5033 }
5034 return;
5035 }
5036
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5037 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
5038 FocusChangeReason reason)
5039 {
5040 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5041 auto sceneSession = GetSceneSession(persistentId);
5042 if (sceneSession == nullptr) {
5043 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5044 return WMError::WM_ERROR_NULLPTR;
5045 }
5046 int32_t callingPid = IPCSkeleton::GetCallingPid();
5047 if (callingPid != sceneSession->GetCallingPid() &&
5048 !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
5049 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
5050 return WMError::WM_ERROR_INVALID_CALLING;
5051 }
5052 auto task = [this, persistentId, isFocused, byForeground, reason]() {
5053 if (isFocused) {
5054 RequestSessionFocus(persistentId, byForeground, reason);
5055 } else {
5056 RequestSessionUnfocus(persistentId, reason);
5057 }
5058 };
5059 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
5060 focusChangeReason_ = reason;
5061 return WMError::WM_OK;
5062 }
5063
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5064 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
5065 FocusChangeReason reason)
5066 {
5067 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5068 auto task = [this, persistentId, isFocused, byForeground, reason]() {
5069 if (isFocused) {
5070 if (reason == FocusChangeReason::FOREGROUND) {
5071 RequestSessionFocusImmediately(persistentId);
5072 return;
5073 }
5074 if (reason == FocusChangeReason::MOVE_UP) {
5075 auto session = GetSceneSession(persistentId);
5076 if (session && !session->IsFocused()) {
5077 PostProcessFocusState state = { true, true, reason };
5078 session->SetPostProcessFocusState(state);
5079 }
5080 return;
5081 }
5082 // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
5083 if (reason == FocusChangeReason::CLICK) {
5084 return;
5085 }
5086 if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
5087 auto session = GetSceneSession(persistentId);
5088 if (session && !session->IsFocused()) {
5089 PostProcessFocusState state = { true, true, reason };
5090 session->SetPostProcessFocusState(state);
5091 }
5092 }
5093 } else {
5094 RequestSessionUnfocus(persistentId, reason);
5095 }
5096 };
5097 taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
5098 return WMError::WM_OK;
5099 }
5100
RequestAllAppSessionUnfocus()5101 void SceneSessionManager::RequestAllAppSessionUnfocus()
5102 {
5103 auto task = [this]() {
5104 RequestAllAppSessionUnfocusInner();
5105 };
5106 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
5107 return;
5108 }
5109
5110 /**
5111 * request focus and ignore its state
5112 * only used when app main window start before foreground
5113 */
RequestSessionFocusImmediately(int32_t persistentId)5114 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
5115 {
5116 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
5117 // base block
5118 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
5119 if (basicCheckRet != WSError::WS_OK) {
5120 return basicCheckRet;
5121 }
5122 auto sceneSession = GetSceneSession(persistentId);
5123 if (sceneSession == nullptr) {
5124 WLOGFE("[WMSComm]session is nullptr");
5125 return WSError::WS_ERROR_INVALID_SESSION;
5126 }
5127 if (!sceneSession->GetFocusable()) {
5128 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
5129 return WSError::WS_DO_NOTHING;
5130 }
5131 if (!sceneSession->IsFocusedOnShow()) {
5132 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
5133 return WSError::WS_DO_NOTHING;
5134 }
5135
5136 // specific block
5137 FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
5138 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
5139 if (specificCheckRet != WSError::WS_OK) {
5140 return specificCheckRet;
5141 }
5142
5143 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5144 if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
5145 needBlockNotifyFocusStatusUntilForeground_ = true;
5146 }
5147 ShiftFocus(sceneSession, false, reason);
5148 return WSError::WS_OK;
5149 }
5150
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)5151 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
5152 {
5153 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
5154 persistentId, byForeground, reason);
5155 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
5156 if (basicCheckRet != WSError::WS_OK) {
5157 return basicCheckRet;
5158 }
5159 auto sceneSession = GetSceneSession(persistentId);
5160 if (sceneSession == nullptr) {
5161 WLOGFE("[WMSComm]session is nullptr");
5162 return WSError::WS_ERROR_INVALID_SESSION;
5163 }
5164 if (!sceneSession->GetFocusable() || !IsSessionVisibleForeground(sceneSession)) {
5165 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
5166 return WSError::WS_DO_NOTHING;
5167 }
5168 if (!sceneSession->IsFocusedOnShow()) {
5169 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
5170 return WSError::WS_DO_NOTHING;
5171 }
5172 if (!sceneSession->IsFocusableOnShow() &&
5173 (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
5174 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
5175 return WSError::WS_DO_NOTHING;
5176 }
5177
5178 // subwindow/dialog state block
5179 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
5180 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
5181 GetSceneSession(sceneSession->GetParentPersistentId()) &&
5182 !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
5183 TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
5184 sceneSession->GetParentPersistentId());
5185 return WSError::WS_DO_NOTHING;
5186 }
5187 // specific block
5188 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
5189 if (specificCheckRet != WSError::WS_OK) {
5190 return specificCheckRet;
5191 }
5192
5193 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5194 needBlockNotifyFocusStatusUntilForeground_ = false;
5195 ShiftFocus(sceneSession, false, reason);
5196 return WSError::WS_OK;
5197 }
5198
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)5199 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
5200 {
5201 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
5202 if (persistentId == INVALID_SESSION_ID) {
5203 WLOGFE("id is invalid");
5204 return WSError::WS_ERROR_INVALID_SESSION;
5205 }
5206 auto focusedSession = GetSceneSession(focusedSessionId_);
5207 if (persistentId != focusedSessionId_ &&
5208 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
5209 TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
5210 return WSError::WS_DO_NOTHING;
5211 }
5212 // if pop menu created by desktop request unfocus, back to desktop
5213 auto lastSession = GetSceneSession(lastFocusedSessionId_);
5214 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
5215 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
5216 RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
5217 TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
5218 return WSError::WS_OK;
5219 }
5220 auto nextSession = GetNextFocusableSession(persistentId);
5221 if (nextSession == nullptr) {
5222 DumpAllSessionFocusableInfo(persistentId);
5223 }
5224
5225 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5226 needBlockNotifyFocusStatusUntilForeground_ = false;
5227
5228 if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
5229 return WSError::WS_OK;
5230 }
5231 if (nextSession && !nextSession->IsSessionForeground() && !nextSession->GetSessionInfo().isSystem_) {
5232 needBlockNotifyFocusStatusUntilForeground_ = true;
5233 }
5234 return ShiftFocus(nextSession, true, reason);
5235 }
5236
RequestAllAppSessionUnfocusInner()5237 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
5238 {
5239 TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
5240 auto focusedSession = GetSceneSession(focusedSessionId_);
5241 if (!focusedSession) {
5242 TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
5243 return WSError::WS_DO_NOTHING;
5244 }
5245 if (!focusedSession->IsAppSession()) {
5246 WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
5247 return WSError::WS_DO_NOTHING;
5248 }
5249 auto nextSession = GetTopFocusableNonAppSession();
5250
5251 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5252 needBlockNotifyFocusStatusUntilForeground_ = false;
5253 return ShiftFocus(nextSession, true, FocusChangeReason::WIND);
5254 }
5255
RequestFocusBasicCheck(int32_t persistentId)5256 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
5257 {
5258 // basic focus rule
5259 if (persistentId == INVALID_SESSION_ID) {
5260 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
5261 return WSError::WS_ERROR_INVALID_SESSION;
5262 }
5263 if (persistentId == focusedSessionId_) {
5264 TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
5265 return WSError::WS_DO_NOTHING;
5266 }
5267 return WSError::WS_OK;
5268 }
5269
5270 /**
5271 * @note @window.focus
5272 * When high zOrder System Session unfocus, check if the last focused app window can focus.
5273 */
CheckLastFocusedAppSessionFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & nextSession)5274 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
5275 sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
5276 {
5277 if (focusedSession == nullptr || nextSession == nullptr) {
5278 return false;
5279 }
5280
5281 TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
5282 lastFocusedAppSessionId_, nextSession->GetPersistentId());
5283
5284 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
5285 return false;
5286 }
5287
5288 if (!focusedSession->IsSystemSessionAboveApp()) {
5289 return false;
5290 }
5291
5292 auto mode = nextSession->GetWindowMode();
5293 // only when next session is app, and in split or floation
5294 if (nextSession->IsAppSession() &&
5295 (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
5296 mode == WindowMode::WINDOW_MODE_FLOATING)) {
5297 if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
5298 WSError::WS_OK) {
5299 return true;
5300 }
5301 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5302 }
5303 return false;
5304 }
5305
5306 /**
5307 * When switching focus, check if the blockingType window has been traversed downwards.
5308 *
5309 * @return true: traversed downwards, false: not.
5310 */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession> & requestSceneSession,sptr<SceneSession> & focusedSession,bool includingAppSession)5311 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
5312 sptr<SceneSession>& focusedSession, bool includingAppSession)
5313 {
5314 uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
5315 uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
5316 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
5317 requestSessionZOrder, focusedSessionZOrder);
5318 if (requestSessionZOrder < focusedSessionZOrder) {
5319 auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
5320 includingAppSession);
5321 uint32_t topNearestBlockingZOrder = 0;
5322 if (topNearestBlockingFocusSession) {
5323 topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
5324 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
5325 topNearestBlockingZOrder: %{public}d", requestSessionZOrder, focusedSessionZOrder,
5326 topNearestBlockingZOrder);
5327 }
5328 if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) {
5329 TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted");
5330 return true;
5331 }
5332 }
5333 TLOGD(WmsLogTag::WMS_FOCUS, "not through");
5334 return false;
5335 }
5336
CheckTopmostWindowFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & sceneSession)5337 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
5338 {
5339 bool isFocusedMainSessionTopmost =
5340 focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
5341 auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
5342 bool isFocusedSessionParentTopmost = parentSession &&
5343 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
5344 if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
5345 (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
5346 return true;
5347 }
5348 return false;
5349 }
5350
CheckRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5351 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5352 {
5353 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
5354 (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
5355 (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
5356 ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
5357 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
5358 return true;
5359 }
5360 return false;
5361 }
5362
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)5363 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
5364 const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
5365 {
5366 if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
5367 focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
5368 return false;
5369 }
5370 if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
5371 return false;
5372 }
5373 return sceneSession->GetZOrder() < focusedSession->GetZOrder();
5374 }
5375
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)5376 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
5377 FocusChangeReason reason)
5378 {
5379 TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
5380 int32_t persistentId = sceneSession->GetPersistentId();
5381 if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5382 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5383 return WSError::WS_ERROR_INVALID_OPERATION;
5384 }
5385 // dialog get focus
5386 if (CheckRequestFocusImmdediately(sceneSession)) {
5387 return WSError::WS_DO_NOTHING;
5388 }
5389 // blocking-type session will block lower zOrder request focus
5390 auto focusedSession = GetSceneSession(focusedSessionId_);
5391 if (focusedSession) {
5392 TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d", reason,
5393 byForeground);
5394 if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
5395 // return ok if focused session is topmost
5396 return WSError::WS_OK;
5397 }
5398 if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
5399 sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
5400 TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
5401 byForeground = false;
5402 }
5403 if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, true)) {
5404 TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
5405 return WSError::WS_DO_NOTHING;
5406 }
5407 if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
5408 !byForeground) {
5409 if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
5410 && focusedSession->IsAppSession()) {
5411 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
5412 return WSError::WS_OK;
5413 }
5414 }
5415 bool isBlockingType = focusedSession->IsAppSession() ||
5416 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
5417 // temp check
5418 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
5419 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
5420 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
5421 persistentId);
5422 return WSError::WS_DO_NOTHING;
5423 }
5424 // desktop click temp check
5425 if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
5426 TLOGW(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
5427 return WSError::WS_DO_NOTHING;
5428 }
5429 }
5430 return WSError::WS_OK;
5431 }
5432
CheckParentSessionVisible(const sptr<SceneSession> & session)5433 bool SceneSessionManager::CheckParentSessionVisible(const sptr<SceneSession>& session)
5434 {
5435 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
5436 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
5437 GetSceneSession(session->GetParentPersistentId()) &&
5438 !IsSessionVisibleForeground(GetSceneSession(session->GetParentPersistentId()))) {
5439 return false;
5440 }
5441 return true;
5442 }
5443
DumpAllSessionFocusableInfo(int32_t persistentId)5444 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
5445 {
5446 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
5447 auto func = [this](sptr<SceneSession> session) {
5448 if (session == nullptr) {
5449 return false;
5450 }
5451 bool parentVisible = CheckParentSessionVisible(session);
5452 bool sessionVisible = IsSessionVisible(session);
5453 TLOGI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
5454 "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
5455 session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
5456 session->GetFocusable(), sessionVisible, parentVisible);
5457 return false;
5458 };
5459 TraverseSessionTree(func, true);
5460 }
5461
GetNextFocusableSession(int32_t persistentId)5462 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
5463 {
5464 TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
5465 bool previousFocusedSessionFound = false;
5466 sptr<SceneSession> ret = nullptr;
5467 auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
5468 if (session == nullptr) {
5469 return false;
5470 }
5471 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5472 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5473 return false;
5474 }
5475 if (previousFocusedSessionFound && session->GetFocusable() &&
5476 session->IsVisible() && CheckParentSessionVisible(session)) {
5477 ret = session;
5478 return true;
5479 }
5480 if (session->GetPersistentId() == persistentId) {
5481 previousFocusedSessionFound = true;
5482 }
5483 return false;
5484 };
5485 TraverseSessionTree(func, true);
5486 return ret;
5487 }
5488
5489 /**
5490 * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
5491 * and it is the closest;
5492 */
GetTopNearestBlockingFocusSession(uint32_t zOrder,bool includingAppSession)5493 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
5494 {
5495 sptr<SceneSession> ret = nullptr;
5496 auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
5497 if (session == nullptr) {
5498 return false;
5499 }
5500 uint32_t sessionZOrder = session->GetZOrder();
5501 if (sessionZOrder <= zOrder) { // must be above the target session
5502 return false;
5503 }
5504 if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5505 TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
5506 return false;
5507 }
5508 auto parentSession = GetSceneSession(session->GetParentPersistentId());
5509 if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
5510 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5511 parentSession->IsTopmost()) {
5512 TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
5513 return false;
5514 }
5515 bool isPhoneOrPad = systemConfig_.uiType_ == UI_TYPE_PHONE || systemConfig_.uiType_ == UI_TYPE_PAD;
5516 bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
5517 (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
5518 (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
5519 if (IsSessionVisibleForeground(session) && isBlockingType) {
5520 ret = session;
5521 return true;
5522 }
5523 return false;
5524 };
5525 TraverseSessionTree(func, false);
5526 return ret;
5527 }
5528
GetTopFocusableNonAppSession()5529 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
5530 {
5531 TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
5532 sptr<SceneSession> ret = nullptr;
5533 auto func = [this, &ret](sptr<SceneSession> session) {
5534 if (session == nullptr) {
5535 return false;
5536 }
5537 if (session->IsAppSession()) {
5538 return true;
5539 }
5540 if (session->GetFocusable() && IsSessionVisibleForeground(session)) {
5541 ret = session;
5542 }
5543 return false;
5544 };
5545 TraverseSessionTree(func, false);
5546 return ret;
5547 }
5548
SetShiftFocusListener(const ProcessShiftFocusFunc & func)5549 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
5550 {
5551 TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
5552 shiftFocusFunc_ = func;
5553 }
5554
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5555 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5556 {
5557 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
5558 notifySCBAfterFocusedFunc_ = func;
5559 }
5560
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5561 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5562 {
5563 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
5564 notifySCBAfterUnfocusedFunc_ = func;
5565 }
5566
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)5567 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
5568 {
5569 WLOGFD("SetCallingSessionIdSessionListenser");
5570 callingSessionIdChangeFunc_ = func;
5571 }
5572
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)5573 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
5574 {
5575 WLOGFD("SetStartUIAbilityErrorListener");
5576 startUIAbilityErrorFunc_ = func;
5577 }
5578
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)5579 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
5580 const AbilityManagerCollaboratorRegisteredFunc& func)
5581 {
5582 auto task = [this, func] {
5583 abilityManagerCollaboratorRegisteredFunc_ = func;
5584 };
5585 taskScheduler_->PostAsyncTask(task, __func__);
5586 }
5587
ShiftFocus(sptr<SceneSession> & nextSession,bool isProactiveUnfocus,FocusChangeReason reason)5588 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, bool isProactiveUnfocus,
5589 FocusChangeReason reason)
5590 {
5591 // unfocus
5592 int32_t focusedId = focusedSessionId_;
5593 auto focusedSession = GetSceneSession(focusedSessionId_);
5594 UpdateFocusStatus(focusedSession, false);
5595 // focus
5596 int32_t nextId = INVALID_SESSION_ID;
5597 if (nextSession == nullptr) {
5598 std::string sessionLog(GetAllSessionFocusInfo());
5599 TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
5600 focusedSessionId_, sessionLog.c_str());
5601 } else {
5602 nextId = nextSession->GetPersistentId();
5603 }
5604 UpdateFocusStatus(nextSession, true);
5605 UpdateHighlightStatus(focusedSession, nextSession, isProactiveUnfocus);
5606 if (shiftFocusFunc_ != nullptr) {
5607 shiftFocusFunc_(nextId);
5608 }
5609 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5610 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5611 if (!scbPrevFocus && scbCurrFocus) {
5612 if (notifySCBAfterFocusedFunc_ != nullptr) {
5613 notifySCBAfterFocusedFunc_();
5614 }
5615 } else if (scbPrevFocus && !scbCurrFocus) {
5616 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5617 notifySCBAfterUnfocusedFunc_();
5618 }
5619 }
5620 TLOGI(WmsLogTag::WMS_FOCUS, "ShiftFocus, focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5621 focusedId, nextId, reason);
5622 return WSError::WS_OK;
5623 }
5624
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5625 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5626 {
5627 if (sceneSession == nullptr) {
5628 if (isFocused) {
5629 SetFocusedSessionId(INVALID_SESSION_ID);
5630 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5631 }
5632 return;
5633 }
5634 TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5635 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5636 // set focused
5637 if (isFocused) {
5638 SetFocusedSessionId(sceneSession->GetPersistentId());
5639 if (sceneSession->IsAppOrLowerSystemSession()) {
5640 lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5641 }
5642 }
5643 sceneSession->UpdateFocus(isFocused);
5644 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5645 NotifyFocusStatus(sceneSession, isFocused);
5646 }
5647 }
5648
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5649 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5650 {
5651 if (sceneSession == nullptr) {
5652 WLOGFE("[WMSComm]session is nullptr");
5653 if (isFocused) {
5654 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5655 NotifyUnFocusedByMission(prevSession);
5656 }
5657 return;
5658 }
5659 int32_t persistentId = sceneSession->GetPersistentId();
5660
5661 TLOGI(WmsLogTag::WMS_FOCUS,
5662 "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5663 sceneSession->GetSessionInfo().bundleName_.c_str(),
5664 sceneSession->GetSessionInfo().abilityName_.c_str(),
5665 sceneSession->GetWindowNameAllType().c_str(),
5666 persistentId, isFocused);
5667 if (isFocused) {
5668 if (IsSessionVisibleForeground(sceneSession)) {
5669 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5670 }
5671 UpdateBrightness(focusedSessionId_);
5672 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5673 }
5674 // notify window manager
5675 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5676 sceneSession->GetWindowId(),
5677 static_cast<DisplayId>(0),
5678 sceneSession->GetCallingPid(),
5679 sceneSession->GetCallingUid(),
5680 sceneSession->GetWindowType(),
5681 sceneSession->GetAbilityToken()
5682 );
5683 SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5684 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5685 sceneSession->NotifyFocusStatus(isFocused);
5686 // notify listenerController
5687 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5688 if (isFocused && MissionChanged(prevSession, sceneSession)) {
5689 NotifyFocusStatusByMission(prevSession, sceneSession);
5690 }
5691 }
5692
5693 /** @note @window.focus */
UpdateHighlightStatus(const sptr<SceneSession> & preSceneSession,const sptr<SceneSession> & currSceneSession,bool isProactiveUnfocus)5694 void SceneSessionManager::UpdateHighlightStatus(const sptr<SceneSession>& preSceneSession,
5695 const sptr<SceneSession>& currSceneSession, bool isProactiveUnfocus)
5696 {
5697 if (preSceneSession == nullptr || currSceneSession == nullptr) {
5698 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5699 return;
5700 }
5701 bool needBlockHighlightNotify = needBlockNotifyFocusStatusUntilForeground_;
5702 if(isProactiveUnfocus){
5703 TLOGD(WmsLogTag::WMS_FOCUS, "proactiveUnfocus");
5704 RemoveHighlightSessionIds(preSceneSession);
5705 }
5706 if(currSceneSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
5707 TLOGD(WmsLogTag::WMS_FOCUS, "exclusively highlighted");
5708 SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5709 return;
5710 }
5711 if(currSceneSession->GetSessionInfo().isSystem_) {
5712 TLOGD(WmsLogTag::WMS_FOCUS, "system highlighted");
5713 AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5714 return;
5715 }
5716 if(currSceneSession->IsSameMainSession(preSceneSession)) {
5717 TLOGD(WmsLogTag::WMS_FOCUS, "related highlighted");
5718 AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5719 return;
5720 }
5721 TLOGD(WmsLogTag::WMS_FOCUS, "highlighted");
5722 SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5723 }
5724
5725 /** @note @window.focus */
SetHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)5726 void SceneSessionManager::SetHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
5727 {
5728 if (sceneSession == nullptr) {
5729 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5730 return;
5731 }
5732 {
5733 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5734 for (auto persistentId : highlightIds_) {
5735 auto session = GetSceneSession(persistentId);
5736 if (session == nullptr) {
5737 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr");
5738 continue;
5739 }
5740 if (sceneSession->GetPersistentId() != persistentId) {
5741 session->UpdateHighlightStatus(false, false);
5742 }
5743 }
5744 sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
5745 highlightIds_.clear();
5746 highlightIds_.insert(sceneSession->GetPersistentId());
5747 }
5748 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
5749 }
5750
5751 /** @note @window.focus */
AddHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)5752 void SceneSessionManager::AddHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
5753 {
5754 if (sceneSession == nullptr) {
5755 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5756 return;
5757 }
5758 sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
5759 {
5760 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5761 highlightIds_.insert(sceneSession->GetPersistentId());
5762 }
5763 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
5764 }
5765
5766 /** @note @window.focus */
RemoveHighlightSessionIds(const sptr<SceneSession> & sceneSession)5767 void SceneSessionManager::RemoveHighlightSessionIds(const sptr<SceneSession>& sceneSession)
5768 {
5769 if (sceneSession == nullptr) {
5770 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5771 return;
5772 }
5773 {
5774 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5775 if (highlightIds_.find(sceneSession->GetPersistentId()) != highlightIds_.end()) {
5776 sceneSession->UpdateHighlightStatus(false, false);
5777 highlightIds_.erase(sceneSession->GetPersistentId());
5778 } else {
5779 TLOGE(WmsLogTag::WMS_FOCUS, "not found scene session with id: %{public}d", sceneSession->GetPersistentId());
5780 }
5781
5782 }
5783 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
5784 }
5785
5786 /** @note @window.focus */
GetHighlightIdsStr()5787 std::string SceneSessionManager::GetHighlightIdsStr()
5788 {
5789 std::ostringstream oss;
5790 {
5791 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5792 for (auto it = highlightIds_.begin(); it != highlightIds_.end(); it++) {
5793 oss << *it;
5794 if(std::next(it) != highlightIds_.end()) {
5795 oss << ", ";
5796 }
5797 }
5798
5799 }
5800 return oss.str();
5801 }
5802
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)5803 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5804 const std::string& reason)
5805 {
5806 uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5807 nlohmann::json payload;
5808 payload.emplace("uid", uid);
5809 payload.emplace("bundleName", bundleName);
5810 payload.emplace("reason", reason);
5811 nlohmann::json reply;
5812 int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5813 return ret;
5814 }
5815
NotifyFocusStatusByMission(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5816 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5817 {
5818 if (listenerController_ != nullptr) {
5819 if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5820 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", prevSession->GetMissionId());
5821 listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5822 }
5823 if (currSession && !currSession->GetSessionInfo().isSystem_) {
5824 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionFocused, id: %{public}d", currSession->GetMissionId());
5825 listenerController_->NotifySessionFocused(currSession->GetMissionId());
5826 }
5827 }
5828 }
5829
NotifyUnFocusedByMission(sptr<SceneSession> & sceneSession)5830 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5831 {
5832 if (listenerController_ == nullptr) {
5833 return;
5834 }
5835 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5836 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", sceneSession->GetMissionId());
5837 listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5838 }
5839 }
5840
MissionChanged(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5841 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5842 {
5843 if (prevSession == nullptr && currSession == nullptr) {
5844 return false;
5845 }
5846 if (prevSession == nullptr || currSession == nullptr) {
5847 return true;
5848 }
5849 return prevSession->GetMissionId() != currSession->GetMissionId();
5850 }
5851
GetAllSessionFocusInfo()5852 std::string SceneSessionManager::GetAllSessionFocusInfo()
5853 {
5854 std::ostringstream os;
5855 auto func = [&os](sptr<SceneSession> session) {
5856 if (session == nullptr) {
5857 WLOGE("sceneSession is nullptr");
5858 return false;
5859 }
5860 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5861 " ,focusable: "<< session->GetFocusable() << ";";
5862 return false;
5863 };
5864 TraverseSessionTree(func, true);
5865 return os.str();
5866 }
5867
UpdateFocus(int32_t persistentId,bool isFocused)5868 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5869 {
5870 auto task = [this, persistentId, isFocused]() {
5871 // notify session and client
5872 auto sceneSession = GetSceneSession(persistentId);
5873 if (sceneSession == nullptr) {
5874 WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5875 return WSError::WS_ERROR_INVALID_WINDOW;
5876 }
5877 WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5878 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5879 // focusId change
5880 if (isFocused) {
5881 SetFocusedSessionId(persistentId);
5882 UpdateBrightness(focusedSessionId_);
5883 FocusIDChange(persistentId, sceneSession);
5884 } else if (persistentId == GetFocusedSessionId()) {
5885 SetFocusedSessionId(INVALID_SESSION_ID);
5886 }
5887 // notify window manager
5888 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5889 sceneSession->GetWindowId(),
5890 static_cast<DisplayId>(0),
5891 sceneSession->GetCallingPid(),
5892 sceneSession->GetCallingUid(),
5893 sceneSession->GetWindowType(),
5894 sceneSession->GetAbilityToken()
5895 );
5896 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5897 WSError res = WSError::WS_OK;
5898 res = sceneSession->UpdateFocus(isFocused);
5899 if (res != WSError::WS_OK) {
5900 return res;
5901 }
5902 WLOGFI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5903 sceneSession->GetSessionInfo().isSystem_);
5904 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
5905 if (isFocused) {
5906 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
5907 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5908 } else {
5909 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5910 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5911 }
5912 }
5913 return WSError::WS_OK;
5914 };
5915
5916 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5917 return WSError::WS_OK;
5918 }
5919
UpdateWindowMode(int32_t persistentId,int32_t windowMode)5920 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5921 {
5922 WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
5923 auto sceneSession = GetSceneSession(persistentId);
5924 if (sceneSession == nullptr) {
5925 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
5926 return WSError::WS_ERROR_INVALID_WINDOW;
5927 }
5928 WindowMode mode = static_cast<WindowMode>(windowMode);
5929 return sceneSession->UpdateWindowMode(mode);
5930 }
5931
GetNormalSingleHandTransform() const5932 SingleHandTransform SceneSessionManager::GetNormalSingleHandTransform() const
5933 {
5934 return singleHandTransform_;
5935 }
5936
NotifySingleHandInfoChange(float singleHandScaleX,float singleHandScaleY,SingleHandMode singleHandMode)5937 void SceneSessionManager::NotifySingleHandInfoChange(
5938 float singleHandScaleX, float singleHandScaleY, SingleHandMode singleHandMode)
5939 {
5940 const char* const funcName = __func__;
5941 taskScheduler_->PostAsyncTask([this, singleHandScaleX, singleHandScaleY, singleHandMode, funcName] {
5942 if (systemConfig_.uiType_ != UI_TYPE_PHONE) {
5943 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: only support phone", funcName);
5944 return;
5945 }
5946 int32_t displayWidth = 0;
5947 int32_t displayHeight = 0;
5948 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5949 if (!GetDisplaySizeById(defaultScreenId, displayWidth, displayHeight)) {
5950 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: get display size failed", funcName);
5951 return;
5952 }
5953 switch (singleHandMode) {
5954 case SingleHandMode::MIDDLE:
5955 singleHandTransform_.posX = 0;
5956 singleHandTransform_.posY = 0;
5957 break;
5958 case SingleHandMode::LEFT:
5959 singleHandTransform_.posX = 0;
5960 singleHandTransform_.posY =
5961 static_cast<int32_t>(static_cast<float>(displayHeight) * (1 - singleHandScaleY));
5962 break;
5963 case SingleHandMode::RIGHT:
5964 singleHandTransform_.posX =
5965 static_cast<int32_t>(static_cast<float>(displayWidth) * (1 - singleHandScaleX));
5966 singleHandTransform_.posY =
5967 static_cast<int32_t>(static_cast<float>(displayHeight) * (1 - singleHandScaleY));
5968 break;
5969 default:
5970 break;
5971 }
5972 singleHandTransform_.scaleX = singleHandScaleX;
5973 singleHandTransform_.scaleY = singleHandScaleY;
5974 {
5975 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5976 for (const auto& [_, sceneSession] : sceneSessionMap_) {
5977 if (sceneSession == nullptr || sceneSession->GetSessionProperty()->GetDisplayId() != defaultScreenId ||
5978 sceneSession->GetWindowName().find("OneHandModeBackground", 0) != std::string::npos) {
5979 continue;
5980 }
5981 sceneSession->SetSingleHandTransform(singleHandTransform_);
5982 sceneSession->NotifySingleHandTransformChange(singleHandTransform_);
5983 }
5984 }
5985 FlushWindowInfoToMMI();
5986 }, funcName);
5987 }
5988
RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc && func)5989 void SceneSessionManager::RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc&& func)
5990 {
5991 getRSNodeByStringIDFunc_ = std::move(func);
5992 }
5993
RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc && func)5994 void SceneSessionManager::RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc&& func)
5995 {
5996 setTopWindowBoundaryByIDFunc_ = std::move(func);
5997 }
5998
RegisterSingleHandContainerNode(const std::string & stringId)5999 void SceneSessionManager::RegisterSingleHandContainerNode(const std::string& stringId)
6000 {
6001 if (getRSNodeByStringIDFunc_ == nullptr) {
6002 TLOGE(WmsLogTag::WMS_LAYOUT, "getRSNodeByStringIDFunc is nullptr");
6003 return;
6004 }
6005 auto rsNode = getRSNodeByStringIDFunc_(stringId);
6006 if (rsNode == nullptr) {
6007 TLOGE(WmsLogTag::WMS_LAYOUT, "node is nullptr");
6008 return;
6009 }
6010 TLOGI(WmsLogTag::WMS_LAYOUT, "get OneHandModeBox node, id: %{public}" PRIu64, rsNode->GetId());
6011 rsInterface_.SetWindowContainer(rsNode->GetId(), true);
6012
6013 if (setTopWindowBoundaryByIDFunc_ == nullptr) {
6014 TLOGE(WmsLogTag::WMS_LAYOUT, "setTopWindowBoundaryByIDFunc is nullptr");
6015 return;
6016 }
6017 setTopWindowBoundaryByIDFunc_(stringId);
6018 }
6019
6020 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6021 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6022 MMI::PointerEvent::PointerItem& pointerItem)
6023 {
6024 struct PointerEventData {
6025 double x;
6026 double y;
6027 uint64_t time;
6028 } pointerEventData = {
6029 .x = pointerItem.GetDisplayX(),
6030 .y = pointerItem.GetDisplayY(),
6031 .time = pointerEvent->GetActionTime()
6032 };
6033
6034 const uint32_t MAX_HMAC_SIZE = 64;
6035 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
6036 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
6037 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
6038 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
6039 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
6040 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
6041 }
6042 }
6043 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
6044
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)6045 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
6046 {
6047 if (!pointerEvent) {
6048 WLOGFE("pointerEvent is null");
6049 return WSError::WS_ERROR_NULLPTR;
6050 }
6051 MMI::PointerEvent::PointerItem pointerItem;
6052 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
6053 WLOGFE("Failed to get pointerItem");
6054 return WSError::WS_ERROR_INVALID_PARAM;
6055 }
6056 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
6057 FillSecCompEnhanceData(pointerEvent, pointerItem);
6058 #endif
6059 TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d,action=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
6060 pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
6061 pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
6062 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
6063 return WSError::WS_OK;
6064 }
6065
SetScreenLocked(const bool isScreenLocked)6066 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
6067 {
6068 isScreenLocked_ = isScreenLocked;
6069 DeleteStateDetectTask();
6070 }
6071
SetUserAuthPassed(bool isUserAuthPassed)6072 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
6073 {
6074 taskScheduler_->PostTask([this, isUserAuthPassed] {
6075 isUserAuthPassed_ = isUserAuthPassed;
6076 }, __func__);
6077 }
6078
DeleteStateDetectTask()6079 void SceneSessionManager::DeleteStateDetectTask()
6080 {
6081 if (!IsScreenLocked()) {
6082 return;
6083 }
6084 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6085 for (auto iter : sceneSessionMap_) {
6086 auto& session = iter.second;
6087 if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
6088 taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
6089 DetectTaskInfo detectTaskInfo;
6090 session->SetDetectTaskInfo(detectTaskInfo);
6091 }
6092 }
6093 }
6094
IsScreenLocked() const6095 bool SceneSessionManager::IsScreenLocked() const
6096 {
6097 return isScreenLocked_;
6098 }
6099
IsUserAuthPassed() const6100 bool SceneSessionManager::IsUserAuthPassed() const
6101 {
6102 return isUserAuthPassed_;
6103 }
6104
RegisterWindowChanged(const WindowChangedFunc & func)6105 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
6106 {
6107 WindowChangedFunc_ = func;
6108 }
6109
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)6110 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
6111 const std::unordered_set<std::string>& privacyBundles)
6112 {
6113 bool needNotify = false;
6114 static int reSendTimes = MAX_RESEND_TIMES;
6115 std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
6116 do {
6117 if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
6118 TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
6119 needNotify = !privacyBundles.empty();
6120 break;
6121 }
6122 const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
6123 if (lastPrivacyBundles.size() != privacyBundles.size()) {
6124 TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
6125 lastPrivacyBundles.size(), privacyBundles.size());
6126 needNotify = true;
6127 break;
6128 }
6129 for (const auto& bundle : lastPrivacyBundles) {
6130 if (privacyBundles.find(bundle) == privacyBundles.end()) {
6131 needNotify = true;
6132 break;
6133 }
6134 }
6135 } while (false);
6136
6137 TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
6138 displayId, needNotify);
6139 if (needNotify) {
6140 reSendTimes = MAX_RESEND_TIMES;
6141 privacyBundleMap_[displayId] = privacyBundles;
6142 } else if (reSendTimes > 0) {
6143 needNotify = true;
6144 reSendTimes--;
6145 privacyBundleMap_[displayId] = privacyBundles;
6146 }
6147 return needNotify;
6148 }
6149
UpdatePrivateStateAndNotify(uint32_t persistentId)6150 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
6151 {
6152 auto sceneSession = GetSceneSession(persistentId);
6153 if (sceneSession == nullptr) {
6154 TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
6155 return;
6156 }
6157
6158 auto sessionProperty = sceneSession->GetSessionProperty();
6159 if (sessionProperty == nullptr) {
6160 TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
6161 return;
6162 }
6163 auto displayId = sessionProperty->GetDisplayId();
6164 std::unordered_set<std::string> privacyBundleList;
6165 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
6166 if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
6167 return;
6168 }
6169
6170 std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
6171 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
6172 !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
6173 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
6174 if (!bundleListForNotify.empty()) {
6175 TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
6176 }
6177 for (const auto& bundle : bundleListForNotify) {
6178 TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
6179 displayId, bundle.c_str());
6180 }
6181 }
6182
UpdatePrivateStateAndNotifyForAllScreens()6183 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
6184 {
6185 auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
6186 for (auto& iter : screenProperties) {
6187 auto displayId = iter.first;
6188 std::unordered_set<std::string> privacyBundleList;
6189 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
6190
6191 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
6192 !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
6193 }
6194 }
6195
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)6196 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
6197 std::unordered_set<std::string>& privacyBundles)
6198 {
6199 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6200 for (const auto& item : sceneSessionMap_) {
6201 sptr<SceneSession> sceneSession = item.second;
6202 if (sceneSession == nullptr) {
6203 TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
6204 continue;
6205 }
6206 auto sessionProperty = sceneSession->GetSessionProperty();
6207 if (sessionProperty == nullptr) {
6208 TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
6209 continue;
6210 }
6211 auto currentDisplayId = sessionProperty->GetDisplayId();
6212 if (displayId != currentDisplayId) {
6213 continue;
6214 }
6215 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
6216 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
6217 if (isForeground && sceneSession->GetParentSession() != nullptr) {
6218 isForeground = isForeground &&
6219 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
6220 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
6221 }
6222 bool isPrivate = sessionProperty->GetPrivacyMode() ||
6223 sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
6224 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
6225 if ((isForeground || IsSystemWindowVisible) && isPrivate) {
6226 if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
6227 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
6228 } else {
6229 TLOGD(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
6230 privacyBundles.insert(sceneSession->GetWindowName());
6231 }
6232 }
6233 }
6234 }
6235
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)6236 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6237 {
6238 NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
6239 this->OnSessionStateChange(persistentId, state);
6240 };
6241 if (sceneSession == nullptr) {
6242 WLOGFE("session is nullptr");
6243 return;
6244 }
6245 sceneSession->SetSessionStateChangeNotifyManagerListener(func);
6246 WLOGFD("RegisterSessionStateChangeFunc success");
6247 }
6248
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)6249 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6250 {
6251 wptr<SceneSessionManager> weakSessionManager = this;
6252 NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
6253 auto sceneSessionManager = weakSessionManager.promote();
6254 if (sceneSessionManager == nullptr) {
6255 return;
6256 }
6257 sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
6258 };
6259 if (sceneSession == nullptr) {
6260 WLOGFE("session is nullptr");
6261 return;
6262 }
6263 sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
6264 }
6265
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)6266 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6267 {
6268 NotifyRequestFocusStatusNotifyManagerFunc func =
6269 [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
6270 this->RequestFocusStatus(persistentId, isFocused, byForeground, reason);
6271 };
6272 if (sceneSession == nullptr) {
6273 WLOGFE("session is nullptr");
6274 return;
6275 }
6276 sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
6277 WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
6278 }
6279
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)6280 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
6281 {
6282 GetStateFromManagerFunc func = [this](const ManagerState key) {
6283 switch (key)
6284 {
6285 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
6286 return this->IsScreenLocked();
6287 break;
6288 default:
6289 return false;
6290 break;
6291 }
6292 };
6293 if (sceneSession == nullptr) {
6294 WLOGFE("session is nullptr");
6295 return;
6296 }
6297 sceneSession->SetGetStateFromManagerListener(func);
6298 WLOGFD("RegisterGetStateFromManagerFunc success");
6299 }
6300
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)6301 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6302 {
6303 SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
6304 const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
6305 if (sceneSession == nullptr || property == nullptr) {
6306 TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
6307 return;
6308 }
6309 switch (action) {
6310 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
6311 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
6312 break;
6313 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
6314 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
6315 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
6316 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
6317 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
6318 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
6319 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6320 break;
6321 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
6322 SetBrightness(sceneSession, property->GetBrightness());
6323 break;
6324 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
6325 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
6326 UpdatePrivateStateAndNotify(property->GetPersistentId());
6327 break;
6328 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
6329 CheckAndNotifyWaterMarkChangedResult();
6330 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6331 break;
6332 case WSPropertyChangeAction::ACTION_UPDATE_MODE:
6333 if (sceneSession->GetSessionProperty() != nullptr) {
6334 ProcessWindowModeType();
6335 }
6336 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6337 break;
6338 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
6339 HandleHideNonSystemFloatingWindows(property, sceneSession);
6340 break;
6341 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
6342 FlushWindowInfoToMMI();
6343 break;
6344 default:
6345 break;
6346 }
6347 };
6348 if (sceneSession != nullptr) {
6349 sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
6350 }
6351 }
6352
OnSessionStateChange(int32_t persistentId,const SessionState & state)6353 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
6354 int32_t persistentId, const SessionState& state)
6355 {
6356 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
6357 WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
6358 auto sceneSession = GetSceneSession(persistentId);
6359 if (sceneSession == nullptr) {
6360 WLOGFD("session is nullptr");
6361 return;
6362 }
6363 switch (state) {
6364 case SessionState::STATE_FOREGROUND:
6365 ProcessFocusWhenForeground(sceneSession);
6366 if (!IsSessionVisibleForeground(sceneSession)) {
6367 sceneSession->SetPostProcessProperty(true);
6368 break;
6369 }
6370 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
6371 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
6372 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
6373 UpdatePrivateStateAndNotify(persistentId);
6374 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6375 ProcessSubSessionForeground(sceneSession);
6376 }
6377 break;
6378 case SessionState::STATE_BACKGROUND:
6379 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
6380 RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
6381 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
6382 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
6383 HandleKeepScreenOn(sceneSession, false);
6384 UpdatePrivateStateAndNotify(persistentId);
6385 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6386 ProcessSubSessionBackground(sceneSession);
6387 }
6388 break;
6389 default:
6390 break;
6391 }
6392 ProcessWindowModeType();
6393 }
6394
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)6395 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
6396 {
6397 auto persistentId = sceneSession->GetPersistentId();
6398 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
6399 persistentId == focusedSessionId_) {
6400 if (needBlockNotifyFocusStatusUntilForeground_) {
6401 needBlockNotifyUnfocusStatus_ = false;
6402 needBlockNotifyFocusStatusUntilForeground_ = false;
6403 NotifyFocusStatus(sceneSession, true);
6404 sceneSession->NotifyHighlightChange(true);
6405 }
6406 } else if (!sceneSession->IsFocusedOnShow()) {
6407 sceneSession->SetFocusedOnShow(true);
6408 } else {
6409 if (Session::IsScbCoreEnabled()) {
6410 ProcessFocusWhenForegroundScbCore(sceneSession);
6411 } else {
6412 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
6413 }
6414 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
6415 }
6416 }
6417
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)6418 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
6419 {
6420 if (sceneSession == nullptr) {
6421 TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
6422 return;
6423 }
6424 if (sceneSession->IsFocusableOnShow()) {
6425 if (IsSessionVisibleForeground(sceneSession)) {
6426 RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
6427 } else {
6428 PostProcessFocusState state = {true, true, FocusChangeReason::APP_FOREGROUND};
6429 sceneSession->SetPostProcessFocusState(state);
6430 }
6431 } else {
6432 TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
6433 sceneSession->GetPersistentId());
6434 }
6435 }
6436
ProcessWindowModeType()6437 void SceneSessionManager::ProcessWindowModeType()
6438 {
6439 if (isScreenLocked_) {
6440 return;
6441 }
6442 NotifyRSSWindowModeTypeUpdate();
6443 }
6444
IsSmallFoldProduct()6445 static bool IsSmallFoldProduct()
6446 {
6447 static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
6448 if (foldScreenType.empty()) {
6449 return false;
6450 }
6451 return foldScreenType[0] == '2';
6452 }
6453
IsInSecondaryScreen(const sptr<SceneSession> & sceneSession)6454 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
6455 {
6456 auto sessionProperty = sceneSession->GetSessionProperty();
6457 if (sessionProperty == nullptr) {
6458 TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
6459 return false;
6460 }
6461 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6462 return sessionProperty->GetDisplayId() != defaultScreenId;
6463 }
6464
CheckWindowModeType()6465 WindowModeType SceneSessionManager::CheckWindowModeType()
6466 {
6467 bool inSplit = false;
6468 bool inFloating = false;
6469 bool fullScreen = false;
6470 bool isSmallFold = IsSmallFoldProduct();
6471 {
6472 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6473 for (const auto& session : sceneSessionMap_) {
6474 if (session.second == nullptr ||
6475 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
6476 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
6477 continue;
6478 }
6479 if (isSmallFold && IsInSecondaryScreen(session.second)) {
6480 continue;
6481 }
6482 auto mode = session.second->GetWindowMode();
6483 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
6484 inSplit = true;
6485 }
6486 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
6487 inFloating = true;
6488 }
6489 if (WindowHelper::IsFullScreenWindow(mode)) {
6490 fullScreen = true;
6491 }
6492 }
6493 }
6494
6495 WindowModeType type;
6496 if (inSplit) {
6497 if (inFloating) {
6498 type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
6499 } else {
6500 type = WindowModeType::WINDOW_MODE_SPLIT;
6501 }
6502 } else {
6503 if (inFloating) {
6504 if (fullScreen) {
6505 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
6506 } else {
6507 type = WindowModeType::WINDOW_MODE_FLOATING;
6508 }
6509 } else if (fullScreen) {
6510 type = WindowModeType::WINDOW_MODE_FULLSCREEN;
6511 } else {
6512 type = WindowModeType::WINDOW_MODE_OTHER;
6513 }
6514 }
6515 return type;
6516 }
6517
NotifyRSSWindowModeTypeUpdate()6518 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
6519 {
6520 WindowModeType type = CheckWindowModeType();
6521 if (lastWindowModeType_ == type) {
6522 return;
6523 }
6524 lastWindowModeType_ = type;
6525 TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
6526 static_cast<uint8_t>(type));
6527 SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
6528 }
6529
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)6530 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
6531 {
6532 if (sceneSession == nullptr) {
6533 WLOGFD("session is nullptr");
6534 return;
6535 }
6536 std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
6537 for (const auto& subSession : sceneSession->GetSubSession()) {
6538 if (subSession == nullptr) {
6539 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
6540 continue;
6541 }
6542 if (subSession->IsTopmost()) {
6543 modalVec.push_back(subSession);
6544 TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
6545 continue;
6546 }
6547 const auto& state = subSession->GetSessionState();
6548 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6549 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
6550 continue;
6551 }
6552 RequestSessionFocus(subSession->GetPersistentId(), true);
6553 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6554 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
6555 }
6556
6557 for (const auto& modal : modalVec) {
6558 if (modal == nullptr) {
6559 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
6560 continue;
6561 }
6562 const auto& state = modal->GetSessionState();
6563 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6564 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
6565 continue;
6566 }
6567 auto modalSession = GetSceneSession(modal->GetPersistentId());
6568 if (modalSession == nullptr) {
6569 TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
6570 continue;
6571 }
6572 NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6573 if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
6574 needBlockNotifyUnfocusStatus_ = false;
6575 needBlockNotifyFocusStatusUntilForeground_ = false;
6576 NotifyFocusStatus(modalSession, true);
6577 }
6578 HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
6579 }
6580 }
6581
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6582 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6583 {
6584 // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
6585 sptr<SceneSession> mainSession = nullptr;
6586 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6587 mainSession = sceneSession;
6588 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6589 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6590 }
6591 if (mainSession == nullptr) {
6592 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6593 return WSError::WS_DO_NOTHING;
6594 }
6595
6596 std::vector<sptr<SceneSession>> topmostVec;
6597 for (auto subSession : mainSession->GetSubSession()) {
6598 if (subSession && subSession->IsTopmost()) {
6599 topmostVec.push_back(subSession);
6600 }
6601 }
6602 if (std::find_if(topmostVec.begin(), topmostVec.end(),
6603 [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6604 != topmostVec.end()) {
6605 TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
6606 return WSError::WS_OK;
6607 }
6608 WSError ret = WSError::WS_DO_NOTHING;
6609 for (auto topmostSession : topmostVec) {
6610 if (topmostSession == nullptr) {
6611 continue;
6612 }
6613 // no need to consider order, since rule of zOrder
6614 if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
6615 ret = WSError::WS_OK;
6616 }
6617 }
6618 return ret;
6619 }
6620
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6621 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6622 {
6623 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
6624 sptr<SceneSession> mainSession = nullptr;
6625 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6626 mainSession = sceneSession;
6627 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6628 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6629 }
6630 if (mainSession == nullptr) {
6631 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6632 return WSError::WS_DO_NOTHING;
6633 }
6634 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
6635 if (std::find_if(dialogVec.begin(), dialogVec.end(),
6636 [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6637 != dialogVec.end()) {
6638 TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
6639 return WSError::WS_OK;
6640 }
6641 WSError ret = WSError::WS_DO_NOTHING;
6642 for (auto dialog : dialogVec) {
6643 if (dialog == nullptr) {
6644 continue;
6645 }
6646 // no need to consider order, since rule of zOrder
6647 if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
6648 ret = WSError::WS_OK;
6649 }
6650 }
6651 return ret;
6652 }
6653
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)6654 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
6655 {
6656 if (sceneSession == nullptr) {
6657 WLOGFD("session is nullptr");
6658 return;
6659 }
6660 for (const auto& subSession : sceneSession->GetSubSession()) {
6661 if (subSession == nullptr) {
6662 WLOGFD("sub session is nullptr");
6663 continue;
6664 }
6665 const auto& state = subSession->GetSessionState();
6666 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6667 WLOGFD("sub session is not active");
6668 continue;
6669 }
6670 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6671 HandleKeepScreenOn(subSession, false);
6672 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
6673 }
6674 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
6675 for (const auto& dialog : dialogVec) {
6676 if (dialog == nullptr) {
6677 TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
6678 continue;
6679 }
6680 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
6681 if (dialogSession == nullptr) {
6682 TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
6683 continue;
6684 }
6685 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6686 HandleKeepScreenOn(dialogSession, false);
6687 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
6688 }
6689 for (const auto& toastSession : sceneSession->GetToastSession()) {
6690 if (toastSession == nullptr) {
6691 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
6692 continue;
6693 }
6694 const auto& state = toastSession->GetSessionState();
6695 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6696 continue;
6697 }
6698 NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6699 HandleKeepScreenOn(toastSession, false);
6700 UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
6701 toastSession->SetActive(false);
6702 toastSession->BackgroundTask();
6703 }
6704 }
6705
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)6706 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
6707 const sptr<WindowSessionProperty>& property)
6708 {
6709 if (sceneSession == nullptr) {
6710 WLOGFD("session is nullptr");
6711 return WSError::WS_ERROR_NULLPTR;
6712 }
6713 auto sessionProperty = sceneSession->GetSessionProperty();
6714 if (sessionProperty == nullptr) {
6715 return WSError::WS_ERROR_NULLPTR;
6716 }
6717 uint32_t flags = property->GetWindowFlags();
6718 uint32_t oldFlags = sessionProperty->GetWindowFlags();
6719 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6720 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6721 !property->GetSystemCalling()) {
6722 WLOGFE("Set window flags permission denied");
6723 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6724 }
6725 sessionProperty->SetWindowFlags(flags);
6726 CheckAndNotifyWaterMarkChangedResult();
6727 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6728 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6729 }
6730 WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
6731 return WSError::WS_OK;
6732 }
6733
CheckAndNotifyWaterMarkChangedResult()6734 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
6735 {
6736 bool currentWaterMarkShowState = false;
6737 {
6738 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6739 for (const auto& iter: sceneSessionMap_) {
6740 auto& session = iter.second;
6741 if (!session) {
6742 continue;
6743 }
6744 auto sessionProperty = session->GetSessionProperty();
6745 if (!sessionProperty) {
6746 continue;
6747 }
6748 bool hasWaterMark = sessionProperty->GetWindowFlags() &
6749 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
6750 bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
6751 if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
6752 currentWaterMarkShowState = true;
6753 break;
6754 }
6755 }
6756 if (combinedExtWindowFlags_.waterMarkFlag) {
6757 TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
6758 currentWaterMarkShowState = true;
6759 }
6760 }
6761 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
6762 lastWaterMarkShowState_ = currentWaterMarkShowState;
6763 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
6764 }
6765 }
6766
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)6767 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
6768 {
6769 WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
6770 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
6771 return WSError::WS_OK;
6772 }
6773
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const6774 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
6775 {
6776 if (!bundleMgr_) {
6777 WLOGFE("bundle manager is nullptr.");
6778 return;
6779 }
6780
6781 AAFwk::Want want;
6782 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
6783 auto uid = abilityInfo.uid;
6784 want.SetParam("uid", uid);
6785 bundleMgr_->ProcessPreload(want);
6786 }
6787
NotifyCompleteFirstFrameDrawing(int32_t persistentId)6788 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
6789 {
6790 auto scnSession = GetSceneSession(persistentId);
6791 if (scnSession == nullptr) {
6792 TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
6793 return;
6794 }
6795
6796 const auto& sessionInfo = scnSession->GetSessionInfo();
6797 if (IsAtomicServiceFreeInstall(sessionInfo)) {
6798 TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
6799 scnSession->GetPersistentId(), scnSession->GetWindowType());
6800 FillSessionInfo(scnSession);
6801 }
6802
6803 TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
6804 scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
6805 sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6806 auto abilityInfoPtr = sessionInfo.abilityInfo;
6807 if (abilityInfoPtr == nullptr) {
6808 TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
6809 return;
6810 }
6811 if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
6812 !(abilityInfoPtr->excludeFromMissions)) {
6813 WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
6814 listenerController_->NotifySessionCreated(persistentId);
6815 }
6816
6817 if (eventHandler_ != nullptr) {
6818 auto task = [persistentId]() {
6819 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6820 };
6821 WLOGFI("Post CompleteFirstFrameDrawing task.");
6822 bool ret = eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6823 if (!ret) {
6824 WLOGFE("Report post first frame task failed. the task name is CompleteFirstFrameDrawing");
6825 }
6826 }
6827
6828 if (taskScheduler_ == nullptr) {
6829 return;
6830 }
6831 auto task = [this, abilityInfoPtr]() {
6832 ProcessPreload(*abilityInfoPtr);
6833 };
6834 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6835 }
6836
NotifySessionMovedToFront(int32_t persistentId)6837 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6838 {
6839 WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
6840 auto scnSession = GetSceneSession(persistentId);
6841 if (scnSession == nullptr) {
6842 WLOGFE("session is invalid with %{public}d", persistentId);
6843 return;
6844 }
6845 WLOGFI("NotifySessionMovedToFront, id: %{public}d, system: %{public}d", scnSession->GetPersistentId(),
6846 scnSession->GetSessionInfo().isSystem_);
6847 if (listenerController_ != nullptr &&
6848 !scnSession->GetSessionInfo().isSystem_ &&
6849 (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
6850 !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6851 listenerController_->NotifySessionMovedToFront(persistentId);
6852 }
6853 }
6854
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)6855 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6856 {
6857 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
6858 auto task = [this, &token, &label]() {
6859 auto sceneSession = FindSessionByToken(token);
6860 if (sceneSession == nullptr) {
6861 WLOGFI("fail to find session by token");
6862 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6863 }
6864 sceneSession->SetSessionLabel(label);
6865 WLOGFI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6866 sceneSession->GetSessionInfo().isSystem_);
6867 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
6868 WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6869 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6870 }
6871 return WSError::WS_OK;
6872 };
6873 return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6874 }
6875
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)6876 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6877 const std::shared_ptr<Media::PixelMap>& icon)
6878 {
6879 WLOGFI("Enter");
6880 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6881 WLOGFE("The caller is not system-app, can not use system-api");
6882 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6883 }
6884
6885 auto task = [this, &token, &icon]() {
6886 auto sceneSession = FindSessionByToken(token);
6887 if (sceneSession == nullptr) {
6888 WLOGFI("fail to find session by token");
6889 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6890 }
6891 sceneSession->SetSessionIcon(icon);
6892 WLOGFI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6893 sceneSession->GetSessionInfo().isSystem_);
6894 if (listenerController_ != nullptr &&
6895 !sceneSession->GetSessionInfo().isSystem_ &&
6896 (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
6897 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6898 WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6899 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6900 }
6901 return WSError::WS_OK;
6902 };
6903 return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6904 }
6905
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)6906 WSError SceneSessionManager::IsValidSessionIds(
6907 const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6908 {
6909 WLOGFI("Enter");
6910 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6911 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6912 auto search = sceneSessionMap_.find(sessionIds.at(i));
6913 if (search == sceneSessionMap_.end() || search->second == nullptr) {
6914 results.push_back(false);
6915 continue;
6916 }
6917 results.push_back(true);
6918 }
6919 return WSError::WS_OK;
6920 }
6921
RegisterSessionListener(const sptr<ISessionListener> & listener)6922 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6923 {
6924 WLOGFI("Enter");
6925 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6926 WLOGFE("The caller is not system-app, can not use system-api");
6927 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6928 }
6929 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6930 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6931 return WSError::WS_ERROR_INVALID_PERMISSION;
6932 }
6933 auto task = [this, &listener]() {
6934 WSError ret = WSError::WS_DO_NOTHING;
6935 if (listenerController_ != nullptr) {
6936 ret = listenerController_->AddSessionListener(listener);
6937 } else {
6938 WLOGFE("The listenerController is nullptr");
6939 }
6940
6941 // app continue report for distributed scheduled service
6942 SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6943 static_cast<int32_t>(ret));
6944
6945 return ret;
6946 };
6947 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6948 }
6949
UnRegisterSessionListener(const sptr<ISessionListener> & listener)6950 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6951 {
6952 WLOGFI("Enter");
6953 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6954 WLOGFE("The caller is not system-app, can not use system-api");
6955 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6956 }
6957 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6958 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6959 return WSError::WS_ERROR_INVALID_PERMISSION;
6960 }
6961 auto task = [this, &listener]() {
6962 if (listenerController_ != nullptr) {
6963 listenerController_->DelSessionListener(listener);
6964 return WSError::WS_OK;
6965 } else {
6966 WLOGFE("The listenerController is nullptr");
6967 return WSError::WS_DO_NOTHING;
6968 }
6969 };
6970 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6971 }
6972
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6973 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6974 std::vector<SessionInfoBean>& sessionInfos)
6975 {
6976 WLOGFI("Enter num max %{public}d", numMax);
6977 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6978 WLOGFE("The caller is not system-app, can not use system-api");
6979 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6980 }
6981 if (!SessionPermission::VerifySessionPermission()) {
6982 WLOGFE("The caller has not permission granted");
6983 return WSError::WS_ERROR_INVALID_PERMISSION;
6984 }
6985 auto task = [this, &deviceId, numMax, &sessionInfos]() {
6986 if (CheckIsRemote(deviceId)) {
6987 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6988 if (ret != ERR_OK) {
6989 return WSError::WS_ERROR_INVALID_PARAM;
6990 } else {
6991 return WSError::WS_OK;
6992 }
6993 }
6994 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6995 std::vector<sptr<SceneSession>> sceneSessionInfos;
6996 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6997 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6998 auto sceneSession = iter->second;
6999 if (sceneSession == nullptr) {
7000 WLOGFE("session is nullptr");
7001 continue;
7002 }
7003 auto sessionInfo = sceneSession->GetSessionInfo();
7004 if (sessionInfo.isSystem_) {
7005 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
7006 continue;
7007 }
7008 auto want = sessionInfo.want;
7009 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
7010 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
7011 sceneSession->GetPersistentId());
7012 continue;
7013 }
7014 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
7015 break;
7016 }
7017 WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
7018 sessionInfo.bundleName_.c_str());
7019 sceneSessionInfos.emplace_back(sceneSession);
7020 }
7021 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
7022 };
7023 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
7024 }
7025
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)7026 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
7027 {
7028 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
7029 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
7030 TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
7031 return WSError::WS_ERROR_INVALID_PERMISSION;
7032 }
7033 if (pid < 0) {
7034 return WSError::WS_ERROR_INVALID_PARAM;
7035 }
7036 auto task = [this, pid, &windowStates] {
7037 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7038 for (const auto& [_, sceneSession] : sceneSessionMap_) {
7039 if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
7040 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7041 MainWindowState windowState;
7042 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
7043 windowState.isVisible_ = sceneSession->GetRSVisible();
7044 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
7045 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
7046 windowStates.emplace_back(windowState);
7047 }
7048 }
7049 return WSError::WS_OK;
7050 };
7051 return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
7052 }
7053
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)7054 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
7055 std::vector<SessionInfoBean>& sessionInfos)
7056 {
7057 TLOGI(WmsLogTag::DEFAULT, "begin");
7058 int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
7059 if (result != ERR_OK) {
7060 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
7061 return result;
7062 }
7063 return ERR_OK;
7064 }
7065
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)7066 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
7067 int32_t persistentId, SessionInfoBean& sessionInfo)
7068 {
7069 WLOGFI("id %{public}d", persistentId);
7070 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7071 WLOGFE("The caller is not system-app, can not use system-api");
7072 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7073 }
7074 if (!SessionPermission::VerifySessionPermission()) {
7075 WLOGFE("The caller has not permission granted");
7076 return WSError::WS_ERROR_INVALID_PERMISSION;
7077 }
7078 auto task = [this, &deviceId, persistentId, &sessionInfo]() {
7079 if (CheckIsRemote(deviceId)) {
7080 int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
7081 if (ret != ERR_OK) {
7082 return WSError::WS_ERROR_INVALID_PARAM;
7083 } else {
7084 return WSError::WS_OK;
7085 }
7086 }
7087 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7088 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7089 iter = sceneSessionMap_.find(persistentId);
7090 if (iter != sceneSessionMap_.end()) {
7091 auto sceneSession = iter->second;
7092 if (sceneSession == nullptr) {
7093 WLOGFE("session: %{public}d is nullptr", persistentId);
7094 return WSError::WS_ERROR_INVALID_PARAM;
7095 }
7096 auto sceneSessionInfo = sceneSession->GetSessionInfo();
7097 if (sceneSessionInfo.isSystem_) {
7098 WLOGFD("sessionId: %{public}d isSystemScene", persistentId);
7099 return WSError::WS_ERROR_INVALID_PARAM;
7100 }
7101 auto want = sceneSessionInfo.want;
7102 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
7103 want->GetElement().GetBundleName().empty()) {
7104 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
7105 persistentId);
7106 return WSError::WS_ERROR_INTERNAL_ERROR;
7107 }
7108 WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
7109 sceneSessionInfo.bundleName_.c_str());
7110 return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
7111 } else {
7112 WLOGFW("sessionId: %{public}d not found", persistentId);
7113 return WSError::WS_ERROR_INVALID_PARAM;
7114 }
7115 };
7116 return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
7117 }
7118
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)7119 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
7120 SessionInfoBean& sessionInfo)
7121 {
7122 TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
7123 continueSessionId.c_str());
7124 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7125 TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
7126 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7127 }
7128 if (!SessionPermission::VerifySessionPermission()) {
7129 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
7130 return WSError::WS_ERROR_INVALID_PERMISSION;
7131 }
7132 auto task = [this, continueSessionId, &sessionInfo]() {
7133 WSError ret = WSError::WS_ERROR_INVALID_SESSION;
7134 {
7135 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7136 for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
7137 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
7138 ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
7139 break;
7140 }
7141 }
7142 }
7143
7144 TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
7145 // app continue report for distributed scheduled service
7146 SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
7147 static_cast<int32_t>(ret));
7148 return ret;
7149 };
7150 return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
7151 }
7152
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)7153 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
7154 int32_t persistentId, SessionInfoBean& sessionInfo)
7155 {
7156 WLOGFI("GetRemoteSessionInfoFromDms begin");
7157 std::vector<SessionInfoBean> sessionVector;
7158 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
7159 if (result != ERR_OK) {
7160 return result;
7161 }
7162 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
7163 if (iter->id == persistentId) {
7164 sessionInfo = *iter;
7165 return ERR_OK;
7166 }
7167 }
7168 WLOGFW("missionId not found");
7169 return ERR_INVALID_VALUE;
7170 }
7171
CheckIsRemote(const std::string & deviceId)7172 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
7173 {
7174 if (deviceId.empty()) {
7175 WLOGFI("CheckIsRemote: deviceId is empty.");
7176 return false;
7177 }
7178 std::string localDeviceId;
7179 if (!GetLocalDeviceId(localDeviceId)) {
7180 WLOGFE("CheckIsRemote: get local deviceId failed");
7181 return false;
7182 }
7183 if (localDeviceId == deviceId) {
7184 WLOGFI("CheckIsRemote: deviceId is local.");
7185 return false;
7186 }
7187 WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
7188 return true;
7189 }
7190
GetLocalDeviceId(std::string & localDeviceId)7191 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
7192 {
7193 auto localNode = std::make_unique<NodeBasicInfo>();
7194 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
7195 if (errCode != ERR_OK) {
7196 WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
7197 return false;
7198 }
7199 if (localNode != nullptr) {
7200 localDeviceId = localNode->networkId;
7201 WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
7202 return true;
7203 }
7204 WLOGFE("localDeviceId null");
7205 return false;
7206 }
7207
AnonymizeDeviceId(const std::string & deviceId)7208 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
7209 {
7210 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
7211 return EMPTY_DEVICE_ID;
7212 }
7213 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
7214 anonDeviceId.append("******");
7215 return anonDeviceId;
7216 }
7217
DumpSessionAll(std::vector<std::string> & infos)7218 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
7219 {
7220 WLOGFI("Dump all session.");
7221 if (!SessionPermission::IsSystemCalling()) {
7222 WLOGFE("DumpSessionAll permission denied!");
7223 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7224 }
7225
7226 auto task = [this, &infos]() {
7227 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
7228 infos.push_back(dumpInfo);
7229 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7230 for (const auto &item : sceneSessionMap_) {
7231 auto& session = item.second;
7232 if (session) {
7233 session->DumpSessionInfo(infos);
7234 }
7235 }
7236 return WSError::WS_OK;
7237 };
7238
7239 return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
7240 }
7241
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)7242 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
7243 {
7244 WLOGFI("Dump session with id %{public}d", persistentId);
7245 if (!SessionPermission::IsSystemCalling()) {
7246 WLOGFE("DumpSessionWithId permission denied!");
7247 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7248 }
7249
7250 auto task = [this, persistentId, &infos]() {
7251 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
7252 infos.push_back(dumpInfo);
7253 auto session = GetSceneSession(persistentId);
7254 if (session) {
7255 session->DumpSessionInfo(infos);
7256 } else {
7257 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
7258 }
7259 return WSError::WS_OK;
7260 };
7261
7262 return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
7263 }
7264
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)7265 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
7266 const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
7267 {
7268 if (bundleMgr_ == nullptr) {
7269 WLOGFE("bundleMgr_ is nullptr");
7270 return WSError::WS_ERROR_NULLPTR;
7271 }
7272 auto elementName = want.GetElement();
7273 int32_t ret{0};
7274 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
7275 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
7276 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
7277 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
7278 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
7279 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
7280 std::vector<AppExecFwk::BundleInfo> bundleInfos;
7281 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
7282 WLOGFD("want is empty queryAllAbilityInfos");
7283 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
7284 if (ret) {
7285 WLOGFE("Query all ability infos from BMS failed!");
7286 return WSError::WS_ERROR_INVALID_PARAM;
7287 }
7288 } else if (!elementName.GetBundleName().empty()) {
7289 AppExecFwk::BundleInfo bundleInfo;
7290 WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
7291 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
7292 if (ret) {
7293 WLOGFE("Query ability info from BMS failed!");
7294 return WSError::WS_ERROR_INVALID_PARAM;
7295 }
7296 bundleInfos.push_back(bundleInfo);
7297 } else {
7298 WLOGFE("invalid want:%{public}s", want.ToString().c_str());
7299 return WSError::WS_ERROR_INVALID_PARAM;
7300 }
7301 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
7302 }
7303
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)7304 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
7305 const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
7306 {
7307 if (bundleMgr_ == nullptr) {
7308 TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
7309 return WSError::WS_ERROR_NULLPTR;
7310 }
7311 if (bundleNames.empty()) {
7312 TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
7313 return WSError::WS_ERROR_INVALID_PARAM;
7314 }
7315 auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
7316 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
7317 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
7318 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
7319 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
7320 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
7321 std::vector<AppExecFwk::BundleInfo> bundleInfos;
7322 auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
7323 if (ret) {
7324 TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
7325 return WSError::WS_ERROR_INVALID_PARAM;
7326 }
7327 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
7328 }
7329
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)7330 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
7331 const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
7332 {
7333 if (bundleMgr_ == nullptr) {
7334 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
7335 return WSError::WS_ERROR_NULLPTR;
7336 }
7337 auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
7338 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
7339 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
7340 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
7341 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
7342 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
7343 AppExecFwk::BundleInfo bundleInfo;
7344 if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
7345 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
7346 return WSError::WS_ERROR_INVALID_PARAM;
7347 }
7348 auto& hapModulesList = bundleInfo.hapModuleInfos;
7349 if (hapModulesList.empty()) {
7350 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
7351 return WSError::WS_ERROR_INVALID_PARAM;
7352 }
7353 auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
7354 for (auto& hapModule : hapModulesList) {
7355 auto& abilityInfoList = hapModule.abilityInfos;
7356 for (auto& abilityInfo : abilityInfoList) {
7357 if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
7358 scbAbilityInfo.abilityInfo_ = abilityInfo;
7359 scbAbilityInfo.sdkVersion_ = sdkVersion;
7360 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
7361 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
7362 return WSError::WS_OK;
7363 }
7364 }
7365 }
7366 TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
7367 return WSError::WS_ERROR_INVALID_PARAM;
7368 }
7369
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)7370 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
7371 std::vector<SCBAbilityInfo>& scbAbilityInfos)
7372 {
7373 if (bundleInfos.empty()) {
7374 WLOGFE("bundleInfos is empty");
7375 return WSError::WS_ERROR_INVALID_PARAM;
7376 }
7377 for (auto& bundleInfo : bundleInfos) {
7378 auto& hapModulesList = bundleInfo.hapModuleInfos;
7379 auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
7380 if (hapModulesList.empty()) {
7381 WLOGFD("hapModulesList is empty");
7382 continue;
7383 }
7384 if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
7385 bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
7386 auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
7387 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
7388 if (iter != hapModulesList.end()) {
7389 SCBAbilityInfo scbAbilityInfo;
7390 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
7391 scbAbilityInfo.sdkVersion_ = sdkVersion;
7392 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
7393 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
7394 scbAbilityInfos.push_back(scbAbilityInfo);
7395 continue;
7396 }
7397 }
7398 for (auto& hapModule : hapModulesList) {
7399 auto& abilityInfoList = hapModule.abilityInfos;
7400 for (auto& abilityInfo : abilityInfoList) {
7401 SCBAbilityInfo scbAbilityInfo;
7402 scbAbilityInfo.abilityInfo_ = abilityInfo;
7403 scbAbilityInfo.sdkVersion_ = sdkVersion;
7404 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
7405 scbAbilityInfos.push_back(scbAbilityInfo);
7406 }
7407 }
7408 }
7409 return WSError::WS_OK;
7410 }
7411
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)7412 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
7413 {
7414 if (abilityInfo.orientationId == 0) {
7415 return;
7416 }
7417 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
7418 if (resConfig == nullptr) {
7419 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
7420 return;
7421 }
7422 std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
7423 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
7424 if (resourceMgr == nullptr) {
7425 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
7426 return;
7427 }
7428 std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
7429 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
7430 TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
7431 }
7432 std::string orientation;
7433 auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
7434 if (ret != Global::Resource::RState::SUCCESS) {
7435 TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
7436 static_cast<int32_t>(ret), abilityInfo.orientationId);
7437 return;
7438 }
7439 if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
7440 TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
7441 return;
7442 }
7443 abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
7444 }
7445
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)7446 WSError SceneSessionManager::TerminateSessionNew(
7447 const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
7448 {
7449 if (info == nullptr) {
7450 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
7451 return WSError::WS_ERROR_INVALID_PARAM;
7452 }
7453 TLOGI(WmsLogTag::WMS_LIFE,
7454 "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
7455 info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
7456 int32_t callingPid = IPCSkeleton::GetCallingPid();
7457 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
7458 auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
7459 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
7460 if (sceneSession == nullptr) {
7461 TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
7462 return WSError::WS_ERROR_INVALID_PARAM;
7463 }
7464 const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
7465 if (!pidCheck &&
7466 !SessionPermission::VerifyPermissionByCallerToken(callerToken,
7467 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7468 TLOGE(WmsLogTag::WMS_LIFE,
7469 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
7470 sceneSession->GetCallingPid(), callingPid);
7471 return WSError::WS_ERROR_INVALID_PERMISSION;
7472 }
7473 WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
7474 return errCode;
7475 };
7476 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
7477 }
7478
SetVmaCacheStatus(bool flag)7479 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
7480 {
7481 WLOGFI("flag: %{public}d", flag);
7482 RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
7483 return WSError::WS_OK;
7484 }
7485
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)7486 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
7487 SessionSnapshot& snapshot, bool isLowResolution)
7488 {
7489 WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
7490 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7491 WLOGFE("The caller is not system-app, can not use system-api");
7492 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7493 }
7494 if (!SessionPermission::VerifySessionPermission()) {
7495 WLOGFE("The caller has not permission granted");
7496 return WSError::WS_ERROR_INVALID_PERMISSION;
7497 }
7498 auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
7499 if (CheckIsRemote(deviceId)) {
7500 int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
7501 if (ret != ERR_OK) {
7502 return WSError::WS_ERROR_INVALID_PARAM;
7503 } else {
7504 return WSError::WS_OK;
7505 }
7506 }
7507 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7508 if (!sceneSession) {
7509 return WSError::WS_ERROR_INVALID_PARAM;
7510 }
7511 auto sessionInfo = sceneSession->GetSessionInfo();
7512 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7513 WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7514 sceneSession->GetPersistentId());
7515 }
7516 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
7517 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
7518 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
7519 auto oriSnapshot = sceneSession->Snapshot();
7520 if (oriSnapshot != nullptr) {
7521 if (isLowResolution) {
7522 OHOS::Media::InitializationOptions options;
7523 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
7524 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
7525 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap
7526 = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
7527 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
7528 } else {
7529 snapshot.snapshot = oriSnapshot;
7530 }
7531 }
7532 return WSError::WS_OK;
7533 };
7534 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
7535 }
7536
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)7537 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
7538 {
7539 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
7540 TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
7541 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7542 }
7543 auto task = [this, persistentId, &snapshot]() {
7544 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7545 if (!sceneSession) {
7546 TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
7547 return WMError::WM_ERROR_INVALID_PARAM;
7548 }
7549 auto sessionInfo = sceneSession->GetSessionInfo();
7550 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7551 TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7552 sceneSession->GetPersistentId());
7553 }
7554 snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
7555 snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
7556 snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
7557 float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
7558 auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale);
7559 if (oriSnapshot != nullptr) {
7560 if (sceneSession->GetFloatingScale() > 1.0f) {
7561 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
7562 }
7563 snapshot.snapshot = oriSnapshot;
7564 TLOGI(WmsLogTag::WMS_SYSTEM, "snapshot WxH = %{public}dx%{public}d",
7565 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
7566 return WMError::WM_OK;
7567 }
7568 return WMError::WM_ERROR_NULLPTR;
7569 };
7570 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
7571 }
7572
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)7573 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
7574 {
7575 if (!SessionPermission::IsSACalling()) {
7576 TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
7577 return WSError::WS_ERROR_INVALID_PERMISSION;
7578 }
7579 TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
7580 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7581 if (sceneSession == nullptr) {
7582 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
7583 return WSError::WS_ERROR_NULLPTR;
7584 }
7585 return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
7586 }
7587
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)7588 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
7589 AAFwk::MissionSnapshot& sessionSnapshot)
7590 {
7591 TLOGI(WmsLogTag::DEFAULT, "begin");
7592 int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
7593 sessionId, sessionSnapshot);
7594 if (result != ERR_OK) {
7595 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
7596 return result;
7597 }
7598 return ERR_OK;
7599 }
7600
GetCollaboratorByType(int32_t collaboratorType)7601 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
7602 {
7603 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
7604 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
7605 auto iter = collaboratorMap_.find(collaboratorType);
7606 if (iter == collaboratorMap_.end()) {
7607 TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
7608 return collaborator;
7609 }
7610 collaborator = iter->second;
7611 if (collaborator == nullptr) {
7612 TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
7613 }
7614 return collaborator;
7615 }
7616
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)7617 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
7618 {
7619 wptr<SceneSession> weakSceneSession(sceneSession);
7620 auto task = [this, weakSceneSession]() {
7621 auto scnSession = weakSceneSession.promote();
7622 if (scnSession == nullptr) {
7623 WLOGFE("session is nullptr");
7624 return WSError::WS_ERROR_NULLPTR;
7625 }
7626 auto persistentId = scnSession->GetPersistentId();
7627 if (!GetSceneSession(persistentId)) {
7628 WLOGFE("session is invalid with %{public}d", persistentId);
7629 return WSError::WS_ERROR_INVALID_SESSION;
7630 }
7631 auto sessionInfo = scnSession->GetSessionInfo();
7632 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
7633 if (!abilitySessionInfo) {
7634 TLOGE(WmsLogTag::WMS_MAIN,
7635 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
7636 return WSError::WS_ERROR_NULLPTR;
7637 }
7638 TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
7639 sessionInfo.callState_, persistentId);
7640 bool isColdStart = false;
7641 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
7642 if (isColdStart) {
7643 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
7644 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
7645 scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
7646 scnSession->ResetSessionConnectState();
7647 }
7648 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
7649 return WSError::WS_OK;
7650 };
7651 std::string taskName = "RequestSceneSessionByCall:PID:" +
7652 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
7653 taskScheduler_->PostAsyncTask(task, taskName);
7654 return WSError::WS_OK;
7655 }
7656
StartAbilityBySpecified(const SessionInfo & sessionInfo)7657 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
7658 {
7659 auto task = [this, sessionInfo]() {
7660 WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
7661 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
7662 AAFwk::Want want;
7663 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
7664 if (sessionInfo.want != nullptr) {
7665 want.SetParams(sessionInfo.want->GetParams());
7666 }
7667 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
7668 };
7669
7670 taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
7671 }
7672
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)7673 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
7674 {
7675 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
7676 if (pid == -1) {
7677 TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
7678 return;
7679 }
7680 int32_t ret = HiSysEventWrite(
7681 HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
7682 "WINDOW_STATE_ERROR",
7683 HiviewDFX::HiSysEvent::EventType::FAULT,
7684 "PID", pid,
7685 "PERSISTENT_ID", persistentId);
7686 if (ret != 0) {
7687 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
7688 }
7689 auto task = [this, pid] {
7690 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7691 for (const auto& [_, sceneSession] : sceneSessionMap_) {
7692 if (!sceneSession || pid != sceneSession->GetCallingPid() ||
7693 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7694 continue;
7695 }
7696 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
7697 if (abilitySessionInfo) {
7698 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
7699 abilitySessionInfo->persistentId);
7700 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
7701 }
7702 }
7703 };
7704 // delay 2000ms, wait for hidumper
7705 taskScheduler_->PostAsyncTask(task, __func__, 2000);
7706 }
7707
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)7708 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
7709 {
7710 if (!targetToken) {
7711 WLOGFE("Token is null, cannot find main window");
7712 return nullptr;
7713 }
7714
7715 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7716 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
7717 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7718 if (pair.second->IsTerminated()) {
7719 return false;
7720 }
7721 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7722 return pair.second->GetAbilityToken() == targetToken;
7723 }
7724 return false;
7725 });
7726 if (iter == sceneSessionMap_.end()) {
7727 WLOGFE("Cannot find session");
7728 return nullptr;
7729 }
7730 return iter->second;
7731 }
7732
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)7733 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
7734 {
7735 if (!SessionPermission::IsSystemCalling()) {
7736 TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
7737 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7738 }
7739 if (targetToken == nullptr) {
7740 TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
7741 return WSError::WS_ERROR_NULLPTR;
7742 }
7743
7744 auto task = [this, persistentId, targetToken]() {
7745 auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
7746 if (scnSession == nullptr) {
7747 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
7748 return WSError::WS_ERROR_NULLPTR;
7749 }
7750 if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
7751 TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
7752 return WSError::WS_OK;
7753 }
7754 scnSession->dialogTargetToken_ = targetToken;
7755 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
7756 if (parentSession == nullptr) {
7757 scnSession->NotifyDestroy();
7758 return WSError::WS_ERROR_INVALID_PARAM;
7759 }
7760 scnSession->SetParentSession(parentSession);
7761 scnSession->SetParentPersistentId(parentSession->GetPersistentId());
7762 UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
7763 TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
7764 persistentId, parentSession->GetPersistentId());
7765 return WSError::WS_OK;
7766 };
7767 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
7768 }
7769
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7770 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7771 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7772 {
7773 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
7774 }
7775
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7776 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7777 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7778 {
7779 auto isSaCall = SessionPermission::IsSACalling();
7780 if (!isSaCall) {
7781 WLOGFE("The interface only support for sa call");
7782 return WMError::WM_ERROR_INVALID_PERMISSION;
7783 }
7784 auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
7785 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7786 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7787 for (auto missionId : missionIds) {
7788 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
7789 if (iter == sceneSessionMap_.end()) {
7790 continue;
7791 }
7792 auto sceneSession = iter->second;
7793 if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
7794 continue;
7795 }
7796 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
7797 if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
7798 surfaceNodeIds.push_back(missionId);
7799 continue;
7800 }
7801 if (sceneSession->GetLeashWinSurfaceNode()) {
7802 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
7803 }
7804 }
7805 return WMError::WM_OK;
7806 };
7807 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
7808 }
7809
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7810 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
7811 const sptr<IWindowManagerAgent>& windowManagerAgent)
7812 {
7813 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7814 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7815 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7816 if (!SessionPermission::IsSystemCalling()) {
7817 WLOGFE("RegisterWindowManagerAgent permission denied!");
7818 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7819 }
7820 } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
7821 if (!SessionPermission::IsSystemServiceCalling()) {
7822 return WMError::WM_ERROR_INVALID_PERMISSION;
7823 }
7824 }
7825 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7826 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7827 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7828 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7829 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7830 if (!SessionPermission::IsSACalling()) {
7831 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7832 return WMError::WM_ERROR_INVALID_PERMISSION;
7833 }
7834 }
7835 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7836 WLOGFE("windowManagerAgent is null");
7837 return WMError::WM_ERROR_NULLPTR;
7838 }
7839 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7840 auto task = [this, windowManagerAgent, type, callingPid]() {
7841 return SessionManagerAgentController::GetInstance()
7842 .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7843 };
7844 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
7845 }
7846
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7847 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
7848 const sptr<IWindowManagerAgent>& windowManagerAgent)
7849 {
7850 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7851 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7852 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7853 if (!SessionPermission::IsSystemCalling()) {
7854 WLOGFE("UnregisterWindowManagerAgent permission denied!");
7855 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7856 }
7857 }
7858 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7859 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7860 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7861 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7862 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7863 if (!SessionPermission::IsSACalling()) {
7864 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7865 return WMError::WM_ERROR_INVALID_PERMISSION;
7866 }
7867 }
7868 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7869 WLOGFE("windowManagerAgent is null");
7870 return WMError::WM_ERROR_NULLPTR;
7871 }
7872 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7873 auto task = [this, windowManagerAgent, type, callingPid]() {
7874 return SessionManagerAgentController::GetInstance()
7875 .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7876 };
7877 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7878 }
7879
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)7880 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7881 {
7882 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7883 }
7884
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)7885 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7886 {
7887 SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7888 }
7889
StartWindowInfoReportLoop()7890 void SceneSessionManager::StartWindowInfoReportLoop()
7891 {
7892 WLOGFD("Report loop");
7893 if (eventHandler_ == nullptr) {
7894 WLOGFE("Report event null");
7895 return ;
7896 }
7897 if (isReportTaskStart_) {
7898 WLOGFE("Report is ReportTask Start");
7899 return;
7900 }
7901 auto task = [this]() {
7902 WindowInfoReporter::GetInstance().ReportRecordedInfos();
7903 ReportWindowProfileInfos();
7904 isReportTaskStart_ = false;
7905 StartWindowInfoReportLoop();
7906 };
7907 int64_t delayTime = 1000 * 60 * 60; // an hour.
7908 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7909 if (!ret) {
7910 WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
7911 return;
7912 }
7913 isReportTaskStart_ = true;
7914 }
7915
InitPersistentStorage()7916 void SceneSessionManager::InitPersistentStorage()
7917 {
7918 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7919 int32_t storageMode = -1;
7920 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7921 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7922 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7923 WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7924 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7925 }
7926 }
7927 }
7928
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)7929 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7930 {
7931 WLOGFD("Called.");
7932 if (!SessionPermission::IsSystemServiceCalling()) {
7933 WLOGFE("Only support for system service.");
7934 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7935 }
7936 auto task = [this, &infos]() {
7937 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7938 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7939 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7940 sptr<SceneSession> sceneSession = iter->second;
7941 if (sceneSession == nullptr) {
7942 WLOGFW("null scene session");
7943 continue;
7944 }
7945 bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7946 sceneSession->IsVisibleForAccessibility() :
7947 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7948 WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7949 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7950 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7951 sceneSession->GetSessionState(), isVisibleForAccessibility);
7952 if (isVisibleForAccessibility) {
7953 FillWindowInfo(infos, iter->second);
7954 }
7955 }
7956 return WMError::WM_OK;
7957 };
7958 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7959 }
7960
CheckUnreliableWindowType(WindowType windowType)7961 static bool CheckUnreliableWindowType(WindowType windowType)
7962 {
7963 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7964 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7965 windowType == WindowType::WINDOW_TYPE_TOAST) {
7966 return true;
7967 }
7968 TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7969 return false;
7970 }
7971
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)7972 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7973 std::vector<sptr<UnreliableWindowInfo>>& infos)
7974 {
7975 if (sceneSession == nullptr) {
7976 TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7977 return;
7978 }
7979 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7980 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7981 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7982 TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7983 return;
7984 }
7985 sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo();
7986 if (info == nullptr) {
7987 TLOGE(WmsLogTag::DEFAULT, "null info.");
7988 return;
7989 }
7990 info->windowId_ = sceneSession->GetPersistentId();
7991 WSRect windowRect = sceneSession->GetSessionRect();
7992 info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7993 info->zOrder_ = sceneSession->GetZOrder();
7994 info->floatingScale_ = sceneSession->GetFloatingScale();
7995 info->scaleX_ = sceneSession->GetScaleX();
7996 info->scaleY_ = sceneSession->GetScaleY();
7997 infos.emplace_back(info);
7998 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7999 }
8000
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)8001 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
8002 std::vector<sptr<UnreliableWindowInfo>>& infos)
8003 {
8004 TLOGD(WmsLogTag::DEFAULT, "Called.");
8005 if (!SessionPermission::IsSystemServiceCalling()) {
8006 TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
8007 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8008 }
8009 auto task = [this, windowId, &infos]() {
8010 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8011 for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
8012 if (sceneSession == nullptr) {
8013 TLOGW(WmsLogTag::DEFAULT, "null scene session");
8014 continue;
8015 }
8016 if (sessionId == windowId) {
8017 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
8018 FillUnreliableWindowInfo(sceneSession, infos);
8019 continue;
8020 }
8021 if (!sceneSession->GetRSVisible()) {
8022 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
8023 continue;
8024 }
8025 TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
8026 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
8027 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
8028 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
8029 if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
8030 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
8031 "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
8032 FillUnreliableWindowInfo(sceneSession, infos);
8033 }
8034 }
8035 return WMError::WM_OK;
8036 };
8037 return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
8038 }
8039
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)8040 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
8041 {
8042 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
8043 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8044 if (sceneSession == nullptr) {
8045 WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
8046 return;
8047 }
8048 wptr<SceneSession> weakSceneSession(sceneSession);
8049 if (processingFlushUIParams_.load()) {
8050 TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
8051 auto task = [this, weakSceneSession, type]() {
8052 auto sceneSession = weakSceneSession.promote();
8053 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8054 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8055 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8056 }
8057 };
8058 taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
8059 return;
8060 }
8061 auto task = [this, weakSceneSession, type]() {
8062 auto sceneSession = weakSceneSession.promote();
8063 NotifyAllAccessibilityInfo();
8064 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8065 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8066 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8067 }
8068 };
8069 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:id:" + std::to_string(persistentId));
8070
8071 auto notifySceneInputTask = [weakSceneSession, type]() {
8072 auto sceneSession = weakSceneSession.promote();
8073 if (sceneSession == nullptr) {
8074 return;
8075 }
8076 SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
8077 };
8078 taskScheduler_->PostAsyncTask(notifySceneInputTask);
8079 }
8080
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)8081 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
8082 const sptr<SceneSession>& sceneSession)
8083 {
8084 if (sceneSession == nullptr) {
8085 WLOGFW("null scene session.");
8086 return false;
8087 }
8088 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
8089 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
8090 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
8091 WLOGFD("filter gesture window.");
8092 return false;
8093 }
8094 sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
8095 if (info == nullptr) {
8096 WLOGFE("null info.");
8097 return false;
8098 }
8099 if (sceneSession->GetSessionInfo().isSystem_) {
8100 info->wid_ = 1;
8101 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
8102 } else {
8103 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
8104 }
8105 info->uiNodeId_ = sceneSession->GetUINodeId();
8106 WSRect wsRect = sceneSession->GetSessionGlobalRectWithSingleHandScale(); // only accessability and mmi need global
8107 info->windowRect_ = { wsRect.posX_, wsRect.posY_, wsRect.width_, wsRect.height_ };
8108 info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
8109 info->type_ = sceneSession->GetWindowType();
8110 info->mode_ = sceneSession->GetWindowMode();
8111 info->layer_ = sceneSession->GetZOrder();
8112 info->scaleVal_ = sceneSession->GetFloatingScale();
8113 info->scaleX_ = sceneSession->GetScaleX();
8114 info->scaleY_ = sceneSession->GetScaleY();
8115 info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
8116 info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
8117 auto property = sceneSession->GetSessionProperty();
8118 if (property != nullptr) {
8119 info->displayId_ = property->GetDisplayId();
8120 info->isDecorEnable_ = property->IsDecorEnable();
8121 }
8122 infos.emplace_back(info);
8123 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
8124 info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
8125 return true;
8126 }
8127
GetSessionSnapshotFilePath(int32_t persistentId)8128 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
8129 {
8130 WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
8131 auto sceneSession = GetSceneSession(persistentId);
8132 if (sceneSession == nullptr) {
8133 WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
8134 return "";
8135 }
8136 wptr<SceneSession> weakSceneSession(sceneSession);
8137 auto task = [this, weakSceneSession]() {
8138 auto scnSession = weakSceneSession.promote();
8139 if (scnSession == nullptr) {
8140 WLOGFE("session is nullptr");
8141 return std::string("");
8142 }
8143 std::string filePath = scnSession->GetSessionSnapshotFilePath();
8144 return filePath;
8145 };
8146 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
8147 }
8148
SelectSesssionFromMap(const uint64_t & surfaceId)8149 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
8150 {
8151 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8152 for (const auto &item : sceneSessionMap_) {
8153 auto sceneSession = item.second;
8154 if (sceneSession == nullptr) {
8155 continue;
8156 }
8157 if (sceneSession->GetSurfaceNode() == nullptr) {
8158 continue;
8159 }
8160 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
8161 return sceneSession;
8162 }
8163 }
8164 return nullptr;
8165 }
8166
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)8167 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
8168 {
8169 WLOGFD("WindowLayerInfoChangeCallback: entry");
8170 std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
8171
8172 auto task = [this, weak]() {
8173 auto weakOcclusionData = weak.lock();
8174 if (weakOcclusionData == nullptr) {
8175 WLOGFE("weak occlusionData is nullptr");
8176 return;
8177 }
8178 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
8179 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
8180 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
8181 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
8182 if (currVisibleData.size() != 0) {
8183 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
8184 }
8185 if (visibilityChangeInfos.size() != 0) {
8186 DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
8187 CacVisibleWindowNum();
8188 }
8189
8190 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
8191 if (currDrawingContentData.size() != 0) {
8192 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
8193 }
8194 if (drawingContentChangeInfos.size() != 0) {
8195 DealwithDrawingContentChange(drawingContentChangeInfos);
8196 }
8197 };
8198 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
8199 }
8200
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)8201 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
8202 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
8203 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
8204 {
8205 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
8206 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
8207 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
8208 switch (windowLayerState) {
8209 case WINDOW_ALL_VISIBLE:
8210 case WINDOW_SEMI_VISIBLE:
8211 case WINDOW_IN_VISIBLE:
8212 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
8213 break;
8214 case WINDOW_LAYER_DRAWING:
8215 currDrawingContentData.emplace_back(iter->first, true);
8216 break;
8217 case WINDOW_LAYER_NO_DRAWING:
8218 currDrawingContentData.emplace_back(iter->first, false);
8219 break;
8220 default:
8221 break;
8222 }
8223 }
8224 }
8225
UpdateSubWindowVisibility(const sptr<SceneSession> & session,WindowVisibilityState visibleState,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8226 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
8227 WindowVisibilityState visibleState,
8228 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
8229 std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
8230 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8231 {
8232 if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
8233 visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8234 auto subSessions = GetSubSceneSession(session->GetWindowId());
8235 if (subSessions.empty()) {
8236 return;
8237 }
8238
8239 RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
8240
8241 for (const auto& subSession : subSessions) {
8242 if (subSession == nullptr) {
8243 continue;
8244 }
8245 if (session->GetCallingPid() != subSession->GetCallingPid() &&
8246 (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData))) {
8247 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
8248 subSession->GetWindowId());
8249 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
8250 }
8251 }
8252 }
8253 }
8254
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8255 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
8256 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8257 {
8258 bool sessionRSVisible = false;
8259 for (const auto& elem : currVisibleData) {
8260 uint64_t surfaceId = elem.first;
8261 WindowVisibilityState visibleState = elem.second;
8262 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
8263 sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
8264 if (visibilitySession == nullptr) {
8265 continue;
8266 }
8267 if (session->GetWindowId() == visibilitySession->GetWindowId()) {
8268 if (isVisible) {
8269 sessionRSVisible = true;
8270 }
8271 break;
8272 }
8273 }
8274 return sessionRSVisible;
8275 }
8276
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)8277 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
8278 WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
8279 std::string& visibilityInfo)
8280 {
8281 if (session == nullptr) {
8282 TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
8283 return;
8284 }
8285 session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8286 session->SetVisibilityState(visibleState);
8287 int32_t windowId = session->GetWindowId();
8288 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
8289 session->NotifyWindowVisibility();
8290 }
8291 windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
8292 windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
8293
8294 visibilityInfo +=
8295 "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
8296 }
8297
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)8298 void SceneSessionManager::RemoveDuplicateSubSession(
8299 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
8300 std::vector<sptr<SceneSession>>& subSessions)
8301 {
8302 for (const auto& elem : visibilityChangeInfo) {
8303 uint64_t surfaceId = elem.first;
8304 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8305 if (session == nullptr) {
8306 continue;
8307 }
8308 for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
8309 auto subSession = *iterator;
8310 if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
8311 iterator = subSessions.erase(iterator);
8312 } else {
8313 ++iterator;
8314 }
8315 }
8316 }
8317 }
8318
GetSubSceneSession(int32_t parentWindowId)8319 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
8320 {
8321 std::vector<sptr<SceneSession>> subSessions;
8322 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8323 for (const auto& iter : sceneSessionMap_) {
8324 auto sceneSession = iter.second;
8325 if (sceneSession == nullptr) {
8326 continue;
8327 }
8328 if (sceneSession->GetParentSession() != nullptr &&
8329 sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
8330 subSessions.push_back(sceneSession);
8331 }
8332 }
8333 return subSessions;
8334 }
8335
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8336 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
8337 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8338 {
8339 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
8340 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
8341 uint32_t i, j;
8342 i = j = 0;
8343 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
8344 if (lastVisibleData_[i].first < currVisibleData[j].first) {
8345 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8346 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8347 }
8348 i++;
8349 } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
8350 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8351 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
8352 }
8353 j++;
8354 } else {
8355 if (lastVisibleData_[i].second != currVisibleData[j].second) {
8356 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
8357 }
8358 i++;
8359 j++;
8360 }
8361 }
8362 for (; i < lastVisibleData_.size(); ++i) {
8363 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8364 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8365 }
8366 }
8367 for (; j < currVisibleData.size(); ++j) {
8368 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8369 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
8370 }
8371 }
8372 lastVisibleData_ = currVisibleData;
8373 return visibilityChangeInfo;
8374 }
8375
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8376 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
8377 visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8378 {
8379 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8380 #ifdef MEMMGR_WINDOW_ENABLE
8381 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
8382 #endif
8383
8384 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
8385 for (const auto& elem : visibilityChangeInfo) {
8386 uint64_t surfaceId = elem.first;
8387 WindowVisibilityState visibleState = elem.second;
8388 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
8389 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8390 if (session == nullptr) {
8391 continue;
8392 }
8393 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
8394 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
8395 if (session->GetParentSession() != nullptr &&
8396 !session->GetParentSession()->IsSessionForeground() &&
8397 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
8398 continue;
8399 }
8400 }
8401 SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
8402 UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
8403 #ifdef MEMMGR_WINDOW_ENABLE
8404 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
8405 session->GetCallingUid(), isVisible));
8406 #endif
8407 CheckAndNotifyWaterMarkChangedResult();
8408 }
8409 if (windowVisibilityInfos.size() != 0) {
8410 WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
8411 visibilityInfo.c_str());
8412 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8413 }
8414 #ifdef MEMMGR_WINDOW_ENABLE
8415 if (memMgrWindowInfos.size() != 0) {
8416 WLOGD("Notify memMgrWindowInfos changed start");
8417 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8418 }
8419 #endif
8420 }
8421
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)8422 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
8423 drawingContentChangeInfo)
8424 {
8425 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
8426 for (const auto& elem : drawingContentChangeInfo) {
8427 uint64_t surfaceId = elem.first;
8428 bool drawingState = elem.second;
8429 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8430 if (session == nullptr) {
8431 continue;
8432 }
8433 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
8434 session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
8435 if (openDebugTrace) {
8436 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
8437 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
8438 }
8439 WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
8440 "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
8441 }
8442 if (windowDrawingContenInfos.size() != 0) {
8443 WLOGFD("Notify WindowDrawingContenInfo changed start");
8444 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
8445 }
8446 }
8447
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)8448 WSError SceneSessionManager::NotifyAppUseControlList(
8449 ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
8450 {
8451 TLOGI(WmsLogTag::WMS_LIFE,
8452 "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
8453 static_cast<int>(type), userId, controlList.size());
8454 if (!SessionPermission::IsSACalling()) {
8455 TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8456 return WSError::WS_ERROR_INVALID_PERMISSION;
8457 }
8458 if (type == ControlAppType::APP_LOCK &&
8459 !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
8460 TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
8461 return WSError::WS_ERROR_INVALID_PERMISSION;
8462 }
8463 if (currentUserId_ != userId) {
8464 if (currentUserId_ != DEFAULT_USERID) {
8465 TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
8466 currentUserId_.load(), userId);
8467 return WSError::WS_ERROR_INVALID_OPERATION;
8468 }
8469 int32_t userIdByUid = GetUserIdByUid(getuid());
8470 if (userId != userIdByUid) {
8471 TLOGW(WmsLogTag::WMS_LIFE,
8472 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
8473 currentUserId_.load(), userId, userIdByUid);
8474 return WSError::WS_ERROR_INVALID_OPERATION;
8475 }
8476 }
8477 taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
8478 if (notifyAppUseControlListFunc_ != nullptr) {
8479 notifyAppUseControlListFunc_(type, userId, controlList);
8480 }
8481
8482 std::vector<sptr<SceneSession>> mainSessions;
8483 for (const auto& appUseControlInfo : controlList) {
8484 GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
8485 if (mainSessions.empty()) {
8486 continue;
8487 }
8488 for (const auto& session : mainSessions) {
8489 session->NotifyUpdateAppUseControl(type, appUseControlInfo.isNeedControl_);
8490 }
8491 mainSessions.clear();
8492 }
8493 }, __func__);
8494 return WSError::WS_OK;
8495 }
8496
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)8497 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
8498 {
8499 taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
8500 notifyAppUseControlListFunc_ = std::move(callback);
8501 }, __func__);
8502 }
8503
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)8504 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
8505 std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
8506 {
8507 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
8508 for (const auto& data : currDrawingContentData) {
8509 uint64_t windowId = data.first;
8510 bool currentDrawingContentState = data.second;
8511 int32_t pid = 0;
8512 bool isChange = false;
8513 if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
8514 continue;
8515 } else {
8516 isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
8517 }
8518 if (isChange) {
8519 processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
8520 }
8521 }
8522 return processDrawingContentChangeInfo;
8523 }
8524
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)8525 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
8526 {
8527 bool preWindowDrawingState = true;
8528 sptr<SceneSession> session = SelectSesssionFromMap(windowId);
8529 if (session == nullptr) {
8530 return false;
8531 }
8532 pid = session->GetCallingPid();
8533 preWindowDrawingState = session->GetDrawingContentState();
8534 session->SetDrawingContentState(currentDrawingContentState);
8535 return preWindowDrawingState;
8536 }
8537
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)8538 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
8539 {
8540 bool isChange = true;
8541 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8542 for (const auto& item : sceneSessionMap_) {
8543 auto sceneSession = item.second;
8544 if (sceneSession == nullptr) {
8545 continue;
8546 }
8547 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
8548 windowId != sceneSession->GetSurfaceNode()->GetId()) {
8549 if (sceneSession->GetDrawingContentState()) {
8550 return false;
8551 }
8552 }
8553 }
8554 return isChange;
8555 }
8556
InitWithRenderServiceAdded()8557 void SceneSessionManager::InitWithRenderServiceAdded()
8558 {
8559 auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
8560 this->WindowLayerInfoChangeCallback(occlusiontionData);
8561 };
8562 WLOGI("RegisterWindowVisibilityChangeCallback");
8563 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
8564 WLOGFE("RegisterWindowVisibilityChangeCallback failed");
8565 }
8566 }
8567
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)8568 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
8569 {
8570 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
8571 WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
8572 return WMError::WM_ERROR_INVALID_PARAM;
8573 }
8574
8575 auto task = [this, sceneType]() {
8576 WLOGFD("Set system animated scene %{public}d.", sceneType);
8577 bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
8578 if (!ret) {
8579 WLOGFE("Set system animated scene failed.");
8580 }
8581 };
8582 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
8583 return WMError::WM_OK;
8584 }
8585
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)8586 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
8587 {
8588 if (!SessionPermission::IsSystemCalling()) {
8589 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
8590 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8591 }
8592 if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
8593 TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
8594 return WSError::WS_ERROR_INVALID_PERMISSION;
8595 }
8596 TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
8597 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
8598 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8599 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
8600 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
8601 WindowType::WINDOW_TYPE_APP_COMPONENT));
8602 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8603 return WSError::WS_OK;
8604 }
8605
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)8606 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
8607 {
8608 if (sceneSession == nullptr) {
8609 WLOGFE("sceneSession is nullptr!");
8610 return;
8611 }
8612 if (sceneSession->GetRSVisible()) {
8613 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8614 #ifdef MEMMGR_WINDOW_ENABLE
8615 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
8616 #endif
8617 sceneSession->SetRSVisible(false);
8618 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8619 sceneSession->ClearExtWindowFlags();
8620 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
8621 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
8622 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
8623 #ifdef MEMMGR_WINDOW_ENABLE
8624 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
8625 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
8626 #endif
8627 WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
8628 sceneSession->GetWindowId(), sceneSession->GetRSVisible());
8629 CheckAndNotifyWaterMarkChangedResult();
8630 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8631 #ifdef MEMMGR_WINDOW_ENABLE
8632 WLOGD("Notify memMgrWindowInfos changed start");
8633 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8634 #endif
8635 }
8636 }
8637
FindSessionByToken(const sptr<IRemoteObject> & token)8638 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
8639 {
8640 if (token == nullptr) {
8641 TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
8642 return nullptr;
8643 }
8644 sptr<SceneSession> session = nullptr;
8645 auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8646 if (pair.second == nullptr) {
8647 return false;
8648 }
8649 return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
8650 };
8651 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8652 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8653 if (iter != sceneSessionMap_.end()) {
8654 session = iter->second;
8655 }
8656 return session;
8657 }
8658
FindSessionByAffinity(std::string affinity)8659 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
8660 {
8661 if (affinity.size() == 0) {
8662 WLOGFI("AbilityInfo affinity is empty");
8663 return nullptr;
8664 }
8665 sptr<SceneSession> session = nullptr;
8666 auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8667 if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
8668 return false;
8669 }
8670 return pair.second->GetSessionInfo().sessionAffinity == affinity;
8671 };
8672 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8673 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8674 if (iter != sceneSessionMap_.end()) {
8675 session = iter->second;
8676 }
8677 return session;
8678 }
8679
PreloadInLakeApp(const std::string & bundleName)8680 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
8681 {
8682 WLOGFD("Enter name %{public}s", bundleName.c_str());
8683 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
8684 if (collaborator != nullptr) {
8685 WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
8686 collaborator->NotifyPreloadAbility(bundleName);
8687 }
8688 }
8689
PendingSessionToForeground(const sptr<IRemoteObject> & token)8690 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
8691 {
8692 TLOGI(WmsLogTag::DEFAULT, "Session is going to foreground");
8693 auto pid = IPCSkeleton::GetCallingRealPid();
8694 if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
8695 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
8696 return WSError::WS_ERROR_INVALID_PERMISSION;
8697 }
8698
8699 auto task = [this, &token]() {
8700 auto session = FindSessionByToken(token);
8701 if (session != nullptr) {
8702 return session->PendingSessionToForeground();
8703 }
8704 TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
8705 return WSError::WS_ERROR_INVALID_PARAM;
8706 };
8707 return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
8708 }
8709
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)8710 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
8711 bool shouldBackToCaller)
8712 {
8713 auto task = [this, &token, shouldBackToCaller] {
8714 auto session = FindSessionByToken(token);
8715 if (session != nullptr) {
8716 return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
8717 }
8718 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
8719 return WSError::WS_ERROR_INVALID_PARAM;
8720 };
8721 return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
8722 }
8723
ClearDisplayStatusBarTemporarilyFlags()8724 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
8725 {
8726 for (auto persistentId : avoidAreaListenerSessionSet_) {
8727 auto sceneSession = GetSceneSession(persistentId);
8728 if (sceneSession == nullptr) {
8729 continue;
8730 }
8731 sceneSession->SetIsDisplayStatusBarTemporarily(false);
8732 }
8733 }
8734
GetFocusSessionToken(sptr<IRemoteObject> & token)8735 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
8736 {
8737 if (!SessionPermission::IsSACalling()) {
8738 WLOGFE("GetFocusSessionToken permission denied!");
8739 return WSError::WS_ERROR_INVALID_PERMISSION;
8740 }
8741 auto task = [this, &token]() {
8742 WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
8743 auto sceneSession = GetSceneSession(focusedSessionId_);
8744 if (sceneSession) {
8745 token = sceneSession->GetAbilityToken();
8746 if (token == nullptr) {
8747 WLOGFE("token is nullptr");
8748 return WSError::WS_ERROR_INVALID_PARAM;
8749 }
8750 return WSError::WS_OK;
8751 }
8752 return WSError::WS_ERROR_INVALID_PARAM;
8753 };
8754 return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
8755 }
8756
GetFocusSessionElement(AppExecFwk::ElementName & element)8757 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
8758 {
8759 AppExecFwk::RunningProcessInfo info;
8760 auto pid = IPCSkeleton::GetCallingRealPid();
8761 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
8762 if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
8763 WLOGFE("GetFocusSessionElement permission denied!");
8764 return WSError::WS_ERROR_INVALID_PERMISSION;
8765 }
8766 auto task = [this, &element]() {
8767 WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
8768 auto sceneSession = GetSceneSession(focusedSessionId_);
8769 if (sceneSession) {
8770 auto sessionInfo = sceneSession->GetSessionInfo();
8771 element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
8772 sessionInfo.abilityName_, sessionInfo.moduleName_);
8773 return WSError::WS_OK;
8774 }
8775 return WSError::WS_ERROR_INVALID_SESSION;
8776 };
8777 return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
8778 }
8779
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)8780 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
8781 {
8782 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8783 auto task = [this, persistentId, haveListener, callingPid]() {
8784 TLOGI(WmsLogTag::WMS_IMMS,
8785 "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
8786 persistentId, haveListener);
8787 auto sceneSession = GetSceneSession(persistentId);
8788 if (sceneSession == nullptr) {
8789 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8790 return WSError::WS_DO_NOTHING;
8791 }
8792 if (callingPid != sceneSession->GetCallingPid()) {
8793 TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
8794 return WSError::WS_ERROR_INVALID_PERMISSION;
8795 }
8796 if (haveListener) {
8797 avoidAreaListenerSessionSet_.insert(persistentId);
8798 UpdateAvoidArea(persistentId);
8799 } else {
8800 avoidAreaListenerSessionSet_.erase(persistentId);
8801 }
8802 return WSError::WS_OK;
8803 };
8804 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
8805 }
8806
UpdateAvoidSessionAvoidArea(WindowType type)8807 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type)
8808 {
8809 bool ret = true;
8810 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
8811 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
8812 for (auto& persistentId : avoidAreaListenerSessionSet_) {
8813 auto sceneSession = GetSceneSession(persistentId);
8814 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8815 continue;
8816 }
8817 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(avoidType);
8818 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
8819 }
8820 }
8821
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)8822 void SceneSessionManager::UpdateNormalSessionAvoidArea(
8823 const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
8824 {
8825 bool ret = true;
8826 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8827 TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
8828 persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
8829 needUpdate = false;
8830 return;
8831 }
8832 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8833 TLOGD(WmsLogTag::WMS_IMMS,
8834 "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
8835 needUpdate = false;
8836 return;
8837 }
8838 sceneSession->UpdateSizeChangeReason(SizeChangeReason::AVOID_AREA_CHANGE);
8839 sceneSession->NotifyClientToUpdateRect("AvoidAreaChange", nullptr);
8840 }
8841
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)8842 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
8843 {
8844 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
8845 auto sceneSession = GetSceneSession(windowId);
8846 if (sceneSession == nullptr) {
8847 WLOGFW("window not exist: %{public}d", windowId);
8848 return;
8849 }
8850
8851 wptr<SceneSession> weakSceneSession(sceneSession);
8852 WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
8853 auto task = [weakSceneSession, startMoving]() -> WSError {
8854 auto scnSession = weakSceneSession.promote();
8855 if (scnSession == nullptr) {
8856 WLOGFW("session is null");
8857 return WSError::WS_ERROR_NULLPTR;
8858 }
8859 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8860 return WSError::WS_OK;
8861 };
8862 return taskScheduler_->PostAsyncTask(task);
8863 }
8864
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)8865 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
8866 const std::string taskName, const int delayTime)
8867 {
8868 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
8869 }
8870
UpdateAvoidArea(int32_t persistentId)8871 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8872 {
8873 auto task = [this, persistentId] {
8874 bool needUpdate = false;
8875 auto sceneSession = GetSceneSession(persistentId);
8876 if (sceneSession == nullptr) {
8877 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8878 return;
8879 }
8880 WindowType type = sceneSession->GetWindowType();
8881 if (sceneSession->IsImmersiveType()) {
8882 UpdateAvoidSessionAvoidArea(type);
8883 } else {
8884 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8885 }
8886 if (needUpdate) {
8887 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8888 }
8889 return;
8890 };
8891 taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8892 return;
8893 }
8894
UpdateGestureBackEnabled(int32_t persistentId)8895 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8896 {
8897 auto task = [this, persistentId] {
8898 auto sceneSession = GetSceneSession(persistentId);
8899 if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8900 TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8901 return;
8902 }
8903 auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8904 if (needEnableGestureBack) {
8905 gestureBackEnableWindowIdSet_.erase(persistentId);
8906 } else {
8907 gestureBackEnableWindowIdSet_.insert(persistentId);
8908 }
8909 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8910 sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8911 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8912 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8913 enterRecent_.load() || !sceneSession->IsFocused()) {
8914 needEnableGestureBack = true;
8915 }
8916 if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8917 gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8918 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8919 } else {
8920 TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8921 }
8922 };
8923 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8924 }
8925
UpdateOccupiedAreaIfNeed(const int32_t & persistentId)8926 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8927 {
8928 auto task = [this, persistentId]() {
8929 sptr<SceneSession> keyboardSession = nullptr;
8930 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8931 for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8932 auto sceneSession = item->second;
8933 if (sceneSession != nullptr &&
8934 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8935 keyboardSession = sceneSession;
8936 break;
8937 }
8938 }
8939 if (keyboardSession == nullptr) {
8940 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8941 return;
8942 }
8943 if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8944 return;
8945 }
8946
8947 keyboardSession->OnCallingSessionUpdated();
8948 return;
8949 };
8950 taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8951 return;
8952 }
8953
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)8954 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8955 {
8956 TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8957 isVisible, persistentId);
8958 auto task = [this, persistentId, isVisible] {
8959 auto sceneSession = GetSceneSession(persistentId);
8960 if (sceneSession == nullptr) {
8961 TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8962 return;
8963 }
8964 sceneSession->SetIsStatusBarVisible(isVisible);
8965 };
8966 taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8967 return WSError::WS_OK;
8968 }
8969
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)8970 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8971 {
8972 WLOGFI("isVisible: %{public}u, "
8973 "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8974 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8975 auto task = [this, isVisible, barArea, displayId]() {
8976 bool isNeedUpdate = true;
8977 {
8978 std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8979 isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8980 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8981 currAINavigationBarAreaMap_[displayId] != barArea;
8982 if (isNeedUpdate) {
8983 isAINavigationBarVisible_ = isVisible;
8984 currAINavigationBarAreaMap_.clear();
8985 currAINavigationBarAreaMap_[displayId] = barArea;
8986 }
8987 if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8988 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8989 currAINavigationBarAreaMap_[displayId] = WSRect();
8990 }
8991 }
8992 if (isNeedUpdate) {
8993 WLOGFI("NotifyAINavigationBar inner: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8994 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8995 for (auto persistentId : avoidAreaListenerSessionSet_) {
8996 NotifySessionAINavigationBarChange(persistentId);
8997 }
8998 }
8999 };
9000 taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
9001 return WSError::WS_OK;
9002 }
9003
NotifySessionAINavigationBarChange(int32_t persistentId)9004 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
9005 {
9006 auto sceneSession = GetSceneSession(persistentId);
9007 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
9008 return;
9009 }
9010 bool isLastFrameLayoutFinished = true;
9011 IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
9012 TLOGI(WmsLogTag::WMS_IMMS, "window [%{public}d] is layout finished: %{public}d",
9013 persistentId, isLastFrameLayoutFinished);
9014 if (isLastFrameLayoutFinished) {
9015 sceneSession->UpdateAvoidArea(
9016 new AvoidArea(sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR)),
9017 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
9018 } else {
9019 sceneSession->MarkAvoidAreaAsDirty();
9020 }
9021 }
9022
GetAINavigationBarArea(uint64_t displayId)9023 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
9024 {
9025 std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
9026 if (currAINavigationBarAreaMap_.count(displayId) == 0) {
9027 return {};
9028 }
9029 return currAINavigationBarAreaMap_[displayId];
9030 }
9031
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)9032 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
9033 {
9034 const auto callingPid = IPCSkeleton::GetCallingRealPid();
9035 auto task = [this, persistentId, haveListener, callingPid]() {
9036 TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
9037 persistentId, haveListener);
9038 auto sceneSession = GetSceneSession(persistentId);
9039 if (sceneSession == nullptr) {
9040 TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
9041 return WSError::WS_DO_NOTHING;
9042 }
9043 if (callingPid != sceneSession->GetCallingPid()) {
9044 TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
9045 return WSError::WS_ERROR_INVALID_PERMISSION;
9046 }
9047 if (haveListener) {
9048 touchOutsideListenerSessionSet_.insert(persistentId);
9049 } else {
9050 touchOutsideListenerSessionSet_.erase(persistentId);
9051 }
9052 return WSError::WS_OK;
9053 };
9054 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
9055 }
9056
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)9057 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
9058 {
9059 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
9060 auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
9061 WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
9062 persistentId, haveListener);
9063 auto sceneSession = GetSceneSession(persistentId);
9064 if (sceneSession == nullptr) {
9065 WLOGFD("sceneSession is nullptr.");
9066 return WSError::WS_DO_NOTHING;
9067 }
9068 if (callingPid != sceneSession->GetCallingPid()) {
9069 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
9070 return WSError::WS_ERROR_INVALID_PERMISSION;
9071 }
9072 if (haveListener) {
9073 windowVisibilityListenerSessionSet_.insert(persistentId);
9074 sceneSession->NotifyWindowVisibility();
9075 } else {
9076 windowVisibilityListenerSessionSet_.erase(persistentId);
9077 }
9078 return WSError::WS_OK;
9079 };
9080 return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
9081 }
9082
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)9083 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
9084 {
9085 processVirtualPixelRatioChangeFunc_ = func;
9086 WLOGFI("SetVirtualPixelRatioChangeListener");
9087 }
9088
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)9089 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
9090 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
9091 {
9092 if (displayInfo == nullptr) {
9093 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
9094 return;
9095 }
9096 auto task = [this, displayInfo]() {
9097 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9098 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
9099 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
9100 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
9101 displayInfo->GetWidth(), displayInfo->GetHeight()
9102 };
9103 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
9104 }
9105 for (const auto &item : sceneSessionMap_) {
9106 auto scnSession = item.second;
9107 if (scnSession == nullptr) {
9108 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
9109 continue;
9110 }
9111 SessionInfo sessionInfo = scnSession->GetSessionInfo();
9112 if (sessionInfo.isSystem_) {
9113 continue;
9114 }
9115 if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
9116 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
9117 scnSession->UpdateDensity();
9118 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
9119 "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
9120 scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
9121 }
9122 }
9123 UpdateDisplayRegion(displayInfo);
9124 return WSError::WS_OK;
9125 };
9126 taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
9127 }
9128
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)9129 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
9130 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
9131 {
9132 if (displayInfo == nullptr) {
9133 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
9134 return;
9135 }
9136 auto task = [this, displayInfo]() {
9137 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9138 for (const auto &item : sceneSessionMap_) {
9139 auto scnSession = item.second;
9140 if (scnSession == nullptr) {
9141 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
9142 continue;
9143 }
9144 if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
9145 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
9146 continue;
9147 }
9148 if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
9149 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
9150 scnSession->GetRotation() != displayInfo->GetRotation()) {
9151 scnSession->UpdateRotationAvoidArea();
9152 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
9153 "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
9154 item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
9155 }
9156 scnSession->SetRotation(displayInfo->GetRotation());
9157 scnSession->UpdateOrientation();
9158 }
9159 UpdateDisplayRegion(displayInfo);
9160 return WSError::WS_OK;
9161 };
9162 taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
9163 }
9164
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)9165 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
9166 {
9167 if (displayInfo == nullptr) {
9168 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
9169 return;
9170 }
9171
9172 auto task = [displayInfo]() -> WSError {
9173 ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
9174 displayInfo->GetScaleX(),
9175 displayInfo->GetScaleY(),
9176 displayInfo->GetPivotX(),
9177 displayInfo->GetPivotY(),
9178 displayInfo->GetTranslateX(),
9179 displayInfo->GetTranslateY());
9180 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
9181 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
9182 return WSError::WS_OK;
9183 };
9184 return taskScheduler_->PostAsyncTask(task);
9185 }
9186
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)9187 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
9188 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
9189 {
9190 WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
9191 switch (type) {
9192 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
9193 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
9194 displayInfo, displayInfoMap, type);
9195 break;
9196 }
9197 case DisplayStateChangeType::UPDATE_ROTATION: {
9198 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
9199 displayInfo, displayInfoMap, type);
9200 break;
9201 }
9202 case DisplayStateChangeType::UPDATE_SCALE: {
9203 SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
9204 break;
9205 }
9206 default:
9207 return;
9208 }
9209 }
9210
OnScreenshot(DisplayId displayId)9211 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
9212 {
9213 SceneSessionManager::GetInstance().OnScreenshot(displayId);
9214 }
9215
OnScreenshot(DisplayId displayId)9216 void SceneSessionManager::OnScreenshot(DisplayId displayId)
9217 {
9218 auto task = [this, displayId]() {
9219 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9220 for (const auto& iter : sceneSessionMap_) {
9221 auto sceneSession = iter.second;
9222 if (sceneSession == nullptr) {
9223 continue;
9224 }
9225 auto state = sceneSession->GetSessionState();
9226 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
9227 sceneSession->NotifyScreenshot();
9228 }
9229 }
9230 };
9231 taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
9232 }
9233
ClearSession(int32_t persistentId)9234 WSError SceneSessionManager::ClearSession(int32_t persistentId)
9235 {
9236 WLOGFI("id: %{public}d", persistentId);
9237 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9238 WLOGFE("The caller is not system-app, can not use system-api");
9239 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9240 }
9241 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9242 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9243 return WSError::WS_ERROR_INVALID_PERMISSION;
9244 }
9245 auto task = [this, persistentId]() {
9246 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
9247 return ClearSession(sceneSession);
9248 };
9249 taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
9250 return WSError::WS_OK;
9251 }
9252
ClearSession(sptr<SceneSession> sceneSession)9253 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
9254 {
9255 WLOGFD("Enter");
9256 if (sceneSession == nullptr) {
9257 WLOGFE("session is nullptr");
9258 return WSError::WS_ERROR_INVALID_SESSION;
9259 }
9260 if (!IsSessionClearable(sceneSession)) {
9261 WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
9262 return WSError::WS_ERROR_INVALID_SESSION;
9263 }
9264 const WSError errCode = sceneSession->Clear();
9265 return errCode;
9266 }
9267
ClearAllSessions()9268 WSError SceneSessionManager::ClearAllSessions()
9269 {
9270 WLOGFD("Enter");
9271 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9272 WLOGFE("The caller is not system-app, can not use system-api");
9273 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9274 }
9275 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9276 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9277 return WSError::WS_ERROR_INVALID_PERMISSION;
9278 }
9279 auto task = [this]() {
9280 std::vector<sptr<SceneSession>> sessionVector;
9281 GetAllClearableSessions(sessionVector);
9282 for (uint32_t i = 0; i < sessionVector.size(); i++) {
9283 ClearSession(sessionVector[i]);
9284 }
9285 return WSError::WS_OK;
9286 };
9287 taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
9288 return WSError::WS_OK;
9289 }
9290
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)9291 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
9292 {
9293 WLOGFD("Enter");
9294 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9295 for (const auto &item : sceneSessionMap_) {
9296 auto scnSession = item.second;
9297 if (IsSessionClearable(scnSession)) {
9298 sessionVector.push_back(scnSession);
9299 }
9300 }
9301 }
9302
LockSession(int32_t sessionId)9303 WSError SceneSessionManager::LockSession(int32_t sessionId)
9304 {
9305 WLOGFI("id: %{public}d", sessionId);
9306 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9307 WLOGFE("The caller is not system-app, can not use system-api");
9308 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9309 }
9310 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9311 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9312 return WSError::WS_ERROR_INVALID_PERMISSION;
9313 }
9314 auto task = [this, sessionId]() {
9315 auto sceneSession = GetSceneSession(sessionId);
9316 if (sceneSession == nullptr) {
9317 WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
9318 return WSError::WS_ERROR_INVALID_PARAM;
9319 }
9320 sceneSession->SetSessionInfoLockedState(true);
9321 return WSError::WS_OK;
9322 };
9323 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
9324 }
9325
UnlockSession(int32_t sessionId)9326 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
9327 {
9328 WLOGFI("id: %{public}d", sessionId);
9329 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9330 WLOGFE("The caller is not system-app, can not use system-api");
9331 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9332 }
9333 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9334 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9335 return WSError::WS_ERROR_INVALID_PERMISSION;
9336 }
9337 auto task = [this, sessionId]() {
9338 auto sceneSession = GetSceneSession(sessionId);
9339 if (sceneSession == nullptr) {
9340 WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
9341 return WSError::WS_ERROR_INVALID_PARAM;
9342 }
9343 sceneSession->SetSessionInfoLockedState(false);
9344 return WSError::WS_OK;
9345 };
9346 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
9347 }
9348
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)9349 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
9350 {
9351 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9352 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9353 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9354 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9355 }
9356 if (!SessionPermission::VerifySessionPermission()) {
9357 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9358 return WSError::WS_ERROR_INVALID_PERMISSION;
9359 }
9360
9361 return WSError::WS_OK;
9362 }
9363
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)9364 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
9365 std::vector<int32_t>& result)
9366 {
9367 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9368 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9369 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9370 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9371 }
9372 if (!SessionPermission::VerifySessionPermission()) {
9373 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9374 return WSError::WS_ERROR_INVALID_PERMISSION;
9375 }
9376
9377 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
9378 return WSError::WS_OK;
9379 }
9380
IsSessionClearable(sptr<SceneSession> scnSession)9381 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
9382 {
9383 if (scnSession == nullptr) {
9384 WLOGFI("scnSession is nullptr");
9385 return false;
9386 }
9387 SessionInfo sessionInfo = scnSession->GetSessionInfo();
9388 if (sessionInfo.abilityInfo == nullptr) {
9389 WLOGFI("scnSession abilityInfo is nullptr");
9390 return false;
9391 }
9392 if (sessionInfo.abilityInfo->excludeFromMissions && !scnSession->IsAnco()) {
9393 WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
9394 return false;
9395 }
9396 if (sessionInfo.abilityInfo->unclearableMission) {
9397 WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
9398 return false;
9399 }
9400 if (sessionInfo.isSystem_) {
9401 WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
9402 return false;
9403 }
9404 if (sessionInfo.lockedState) {
9405 WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
9406 return false;
9407 }
9408
9409 return true;
9410 }
9411
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)9412 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
9413 const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
9414 {
9415 WLOGFI("type: %{public}d", type);
9416 auto isSaCall = SessionPermission::IsSACalling();
9417 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9418 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9419 return WSError::WS_ERROR_INVALID_PERMISSION;
9420 }
9421 if (!CheckCollaboratorType(type)) {
9422 WLOGFW("collaborator register failed, invalid type.");
9423 return WSError::WS_ERROR_INVALID_TYPE;
9424 }
9425 {
9426 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9427 collaboratorMap_[type] = impl;
9428 }
9429 auto task = [this] {
9430 if (abilityManagerCollaboratorRegisteredFunc_) {
9431 abilityManagerCollaboratorRegisteredFunc_();
9432 }
9433 };
9434 taskScheduler_->PostTask(task, __func__);
9435 return WSError::WS_OK;
9436 }
9437
UnregisterIAbilityManagerCollaborator(int32_t type)9438 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
9439 {
9440 WLOGFI("type: %{public}d", type);
9441 auto isSaCall = SessionPermission::IsSACalling();
9442 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9443 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9444 return WSError::WS_ERROR_INVALID_PERMISSION;
9445 }
9446 if (!CheckCollaboratorType(type)) {
9447 WLOGFE("collaborator unregister failed, invalid type.");
9448 return WSError::WS_ERROR_INVALID_TYPE;
9449 }
9450 {
9451 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9452 collaboratorMap_.erase(type);
9453 }
9454 return WSError::WS_OK;
9455 }
9456
CheckCollaboratorType(int32_t type)9457 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
9458 {
9459 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
9460 WLOGFD("type is invalid");
9461 return false;
9462 }
9463 return true;
9464 }
9465
CheckIfReuseSession(SessionInfo & sessionInfo)9466 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
9467 {
9468 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
9469 sessionInfo.moduleName_);
9470 if (abilityInfo == nullptr) {
9471 WLOGFE("abilityInfo is nullptr!");
9472 return BrokerStates::BROKER_UNKOWN;
9473 }
9474 sessionInfo.abilityInfo = abilityInfo;
9475 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
9476 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
9477 collaboratorType = CollaboratorType::RESERVE_TYPE;
9478 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
9479 collaboratorType = CollaboratorType::OTHERS_TYPE;
9480 }
9481 if (!CheckCollaboratorType(collaboratorType)) {
9482 WLOGFW("checked not collaborator!");
9483 return BrokerStates::BROKER_UNKOWN;
9484 }
9485 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
9486 sessionInfo.collaboratorType_ = collaboratorType;
9487 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9488 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
9489 WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
9490 sessionInfo.reuse = true;
9491 } else {
9492 sessionInfo.reuse = false;
9493 }
9494 WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
9495 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
9496 return resultValue;
9497 }
9498
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)9499 BrokerStates SceneSessionManager::NotifyStartAbility(
9500 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
9501 {
9502 WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
9503 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9504 if (collaborator == nullptr) {
9505 return BrokerStates::BROKER_UNKOWN;
9506 }
9507 if (sessionInfo.want == nullptr) {
9508 WLOGFI("sessionInfo.want is nullptr, init");
9509 sessionInfo.want = std::make_shared<AAFwk::Want>();
9510 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
9511 sessionInfo.moduleName_);
9512 }
9513 auto accessTokenIDEx = sessionInfo.callingTokenId_;
9514 if (collaborator != nullptr) {
9515 containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
9516 std::chrono::system_clock::now().time_since_epoch()).count();
9517
9518 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9519 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
9520 WLOGFI("want affinity exit %{public}s.", affinity.c_str());
9521 return BrokerStates::BROKER_UNKOWN;
9522 }
9523 sessionInfo.want->SetParam("oh_persistentId", persistentId);
9524 int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
9525 currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
9526 WLOGFI("collaborator ret: %{public}d", ret);
9527 if (ret == 0) {
9528 return BrokerStates::BROKER_STARTED;
9529 } else {
9530 return BrokerStates::BROKER_NOT_START;
9531 }
9532 }
9533 return BrokerStates::BROKER_UNKOWN;
9534 }
9535
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)9536 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
9537 {
9538 if (sceneSession == nullptr) {
9539 WLOGFE("sceneSession is nullptr");
9540 return;
9541 }
9542 if (sessionInfo.want == nullptr) {
9543 WLOGFI("sessionInfo.want is nullptr");
9544 return;
9545 }
9546 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9547 if (collaborator == nullptr) {
9548 return;
9549 }
9550 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9551 if (abilitySessionInfo == nullptr) {
9552 WLOGFE("abilitySessionInfo is nullptr");
9553 return;
9554 }
9555 abilitySessionInfo->want = *(sessionInfo.want);
9556 if (collaborator != nullptr) {
9557 int32_t missionId = abilitySessionInfo->persistentId;
9558 std::string bundleName = sessionInfo.bundleName_;
9559 int64_t timestamp = containerStartAbilityTime_;
9560 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
9561 WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
9562 missionId, bundleName.c_str());
9563 collaborator->NotifyMissionCreated(abilitySessionInfo);
9564 }
9565 }
9566
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)9567 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
9568 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
9569 {
9570 WLOGFD("type: %{public}d", collaboratorType);
9571 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9572 if (collaborator != nullptr) {
9573 WLOGFI("called NotifyLoadAbility");
9574 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
9575 }
9576 }
9577
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)9578 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
9579 {
9580 WLOGFD("Enter");
9581 if (sceneSession == nullptr) {
9582 WLOGFE("sceneSession is nullptr");
9583 return;
9584 }
9585 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9586 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9587 if (collaborator != nullptr) {
9588 WLOGFI("called UpdateMissionInfo");
9589 collaborator->UpdateMissionInfo(abilitySessionInfo);
9590 }
9591 }
9592
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)9593 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
9594 {
9595 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9596 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9597 if (collaborator != nullptr) {
9598 WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
9599 collaborator->NotifyMoveMissionToForeground(persistentId);
9600 }
9601 }
9602
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)9603 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
9604 {
9605 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9606 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9607 if (collaborator != nullptr) {
9608 WLOGFI("called NotifyClearMission %{public}d", persistentId);
9609 collaborator->NotifyClearMission(persistentId);
9610 }
9611 }
9612
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)9613 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
9614 {
9615 if (sceneSession == nullptr) {
9616 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
9617 return false;
9618 }
9619 std::string sessionAffinity;
9620 TLOGI(WmsLogTag::WMS_LIFE, "call");
9621 if (sceneSession->GetSessionInfo().want != nullptr) {
9622 sessionAffinity = sceneSession->GetSessionInfo().want
9623 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9624 }
9625 if (sessionAffinity.empty()) {
9626 TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
9627 BrokerStates notifyReturn = NotifyStartAbility(
9628 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
9629 if (notifyReturn == BrokerStates::BROKER_NOT_START) {
9630 TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
9631 return false;
9632 }
9633 }
9634 if (sceneSession->GetSessionInfo().want != nullptr) {
9635 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
9636 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
9637 TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
9638 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
9639 sceneSession->GetSessionInfo().sessionAffinity.c_str());
9640 } else {
9641 TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
9642 }
9643 return true;
9644 }
9645
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)9646 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
9647 {
9648 if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
9649 return false;
9650 }
9651 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
9652 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
9653 return true;
9654 }
9655
AddWindowDragHotArea(uint32_t type,WSRect & area)9656 void SceneSessionManager::AddWindowDragHotArea(uint32_t type, WSRect& area)
9657 {
9658 WLOGFI("type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
9659 "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
9660 SceneSession::AddOrUpdateWindowDragHotArea(type, area);
9661 }
9662
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)9663 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
9664 {
9665 auto task = [this, persistentId, isMaximize]() -> WSError {
9666 WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
9667 auto sceneSession = GetSceneSession(persistentId);
9668 if (sceneSession == nullptr) {
9669 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9670 return WSError::WS_ERROR_INVALID_WINDOW;
9671 }
9672 sceneSession->UpdateMaximizeMode(isMaximize);
9673 return WSError::WS_OK;
9674 };
9675 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
9676 return WSError::WS_OK;
9677 }
9678
GetIsLayoutFullScreen(bool & isLayoutFullScreen)9679 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
9680 {
9681 auto task = [this, &isLayoutFullScreen]() {
9682 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9683 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9684 auto sceneSession = item->second;
9685 if (sceneSession == nullptr) {
9686 WLOGFE("Session is nullptr");
9687 continue;
9688 }
9689 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9690 continue;
9691 }
9692 auto state = sceneSession->GetSessionState();
9693 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9694 continue;
9695 }
9696 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9697 continue;
9698 }
9699 auto property = sceneSession->GetSessionProperty();
9700 if (property == nullptr) {
9701 WLOGFE("Property is nullptr");
9702 continue;
9703 }
9704 isLayoutFullScreen = property->IsLayoutFullScreen();
9705 auto persistentId = sceneSession->GetPersistentId();
9706 if (isLayoutFullScreen) {
9707 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
9708 return WSError::WS_OK;
9709 } else {
9710 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
9711 }
9712 }
9713 WLOGFD("No immersive window");
9714 return WSError::WS_OK;
9715 };
9716
9717 taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
9718 return WSError::WS_OK;
9719 }
9720
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)9721 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
9722 {
9723 auto scnSession = GetSceneSession(persistentId);
9724 if (!scnSession) {
9725 WLOGFE("session is nullptr");
9726 return WSError::WS_ERROR_INVALID_WINDOW;
9727 }
9728 auto fromScreenId = scnSession->GetSessionInfo().screenId_;
9729 scnSession->SetScreenId(screenId);
9730 auto sessionProperty = scnSession->GetSessionProperty();
9731 if (!sessionProperty) {
9732 WLOGFE("Property is null, synchronous screenId failed");
9733 return WSError::WS_ERROR_NULLPTR;
9734 }
9735 sessionProperty->SetDisplayId(screenId);
9736 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, move display %{public}" PRIu64 "from %{public}" PRIu64,
9737 scnSession->GetPersistentId(), screenId, fromScreenId);
9738 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
9739 scnSession->NotifyDisplayMove(fromScreenId, screenId);
9740 scnSession->UpdateDensity();
9741 return WSError::WS_OK;
9742 }
9743
NotifyStackEmpty(int32_t persistentId)9744 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
9745 {
9746 TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
9747 auto task = [this, persistentId]() {
9748 auto scnSession = GetSceneSession(persistentId);
9749 if (!scnSession) {
9750 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
9751 return WSError::WS_ERROR_INVALID_WINDOW;
9752 }
9753 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
9754 return WSError::WS_OK;
9755 };
9756 taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
9757 return WSError::WS_OK;
9758 }
9759
OnImmersiveStateChange(bool & immersive)9760 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
9761 {
9762 immersive = SceneSessionManager::GetInstance().GetImmersiveState();
9763 }
9764
GetImmersiveState()9765 bool SceneSessionManager::GetImmersiveState()
9766 {
9767 return taskScheduler_->PostSyncTask([this, where = __func__] {
9768 bool isPcOrPadFreeMultiWindowMode = false;
9769 IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
9770 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9771 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9772 if (sceneSession == nullptr) {
9773 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
9774 continue;
9775 }
9776 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9777 continue;
9778 }
9779 auto state = sceneSession->GetSessionState();
9780 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9781 continue;
9782 }
9783 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9784 continue;
9785 }
9786 if (isPcOrPadFreeMultiWindowMode) {
9787 if (sceneSession->IsLayoutFullScreen()) {
9788 return true;
9789 }
9790 continue;
9791 }
9792 auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
9793 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
9794 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
9795 sceneSession->GetPersistentId());
9796 return true;
9797 } else {
9798 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
9799 sceneSession->GetPersistentId());
9800 break;
9801 }
9802 }
9803 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
9804 return false;
9805 }, __func__);
9806 }
9807
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)9808 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
9809 bool withAnimation)
9810 {
9811 session->NotifySessionForeground(reason, withAnimation);
9812 }
9813
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)9814 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
9815 bool withAnimation, bool isFromInnerkits)
9816 {
9817 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
9818 }
9819
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)9820 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
9821 {
9822 auto sceneSession = GetSceneSession(persistentId);
9823 if (sceneSession == nullptr) {
9824 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9825 return WSError::WS_ERROR_INVALID_WINDOW;
9826 }
9827 return sceneSession->UpdateTitleInTargetPos(isShow, height);
9828 }
9829
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9830 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9831 {
9832 WLOGFI("AppAnrListener OnAppDebugStarted");
9833 if (debugInfos.empty()) {
9834 WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9835 return;
9836 }
9837 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
9838 }
9839
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9840 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9841 {
9842 WLOGFI("AppAnrListener OnAppDebugStoped");
9843 if (debugInfos.empty()) {
9844 WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9845 return;
9846 }
9847 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
9848 }
9849
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)9850 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9851 {
9852 if (!Session::IsScbCoreEnabled()) {
9853 return;
9854 }
9855 if (onFlushUIParamsFunc_ != nullptr) {
9856 onFlushUIParamsFunc_();
9857 }
9858 auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9859 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9860 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9861 {
9862 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9863 nextFlushCompletedCV_.notify_all();
9864 }
9865 std::vector<uint32_t> startingAppZOrderList;
9866 processingFlushUIParams_.store(true);
9867 {
9868 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9869 for (const auto& item : sceneSessionMap_) {
9870 auto sceneSession = item.second;
9871 if (sceneSession == nullptr) {
9872 continue;
9873 }
9874 if (sceneSession->GetSessionInfo().screenId_ != SCREEN_ID_INVALID &&
9875 sceneSession->GetSessionInfo().screenId_ != screenId) {
9876 continue;
9877 }
9878 auto iter = uiParams.find(sceneSession->GetPersistentId());
9879 if (iter != uiParams.end()) {
9880 if (sceneSession->GetSessionInfo().screenId_ == SCREEN_ID_INVALID) {
9881 sceneSession->SetScreenIdOnServer(screenId);
9882 }
9883 if ((systemConfig_.uiType_ == UI_TYPE_PHONE ||
9884 (systemConfig_.uiType_ == UI_TYPE_PAD && !systemConfig_.IsFreeMultiWindowMode())) &&
9885 sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
9886 startingAppZOrderList.push_back(iter->second.zOrder_);
9887 sceneSession->SetStartingBeforeVisible(false);
9888 }
9889 sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9890 } else {
9891 sessionMapDirty_ |= sceneSession->UpdateUIParam();
9892 }
9893 }
9894 }
9895 processingFlushUIParams_.store(false);
9896
9897 // post process if dirty
9898 if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9899 static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9900 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9901 for (const auto& item : uiParams) {
9902 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f"
9903 " transY:%{public}f, needSync:%{public}d, intreactive:%{public}d", item.first, item.second.zOrder_,
9904 item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
9905 item.second.needSync_, item.second.interactive_);
9906 }
9907 ProcessUpdateLastFocusedAppId(startingAppZOrderList);
9908 ProcessFocusZOrderChange(sessionMapDirty_);
9909 PostProcessFocus();
9910 PostProcessProperty(sessionMapDirty_);
9911 NotifyAllAccessibilityInfo();
9912 AnomalyDetection::SceneZOrderCheckProcess();
9913 } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9914 PostProcessProperty(sessionMapDirty_);
9915 }
9916 FlushWindowInfoToMMI();
9917 sessionMapDirty_ = 0;
9918 {
9919 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9920 for (const auto& item : sceneSessionMap_) {
9921 auto sceneSession = item.second;
9922 if (sceneSession == nullptr) {
9923 continue;
9924 }
9925 sceneSession->ResetSizeChangeReasonIfDirty();
9926 sceneSession->ResetDirtyFlags();
9927 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9928 sceneSession->SetUIStateDirty(false);
9929 }
9930 }
9931 }
9932 };
9933 taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9934 }
9935
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)9936 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
9937 {
9938 TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu", lastFocusedAppSessionId_,
9939 zOrderList.size());
9940 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || zOrderList.empty()) {
9941 return;
9942 }
9943 auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId_);
9944 if (lastFocusedAppSession == nullptr) {
9945 return;
9946 }
9947 uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
9948 auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
9949 return zOrder > lastFocusedAppZOrder;
9950 });
9951 if (it != zOrderList.end()) {
9952 TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
9953 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
9954 }
9955 }
9956
ProcessFocusZOrderChange(uint32_t dirty)9957 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
9958 {
9959 if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9960 return;
9961 }
9962 if (systemConfig_.uiType_ != UI_TYPE_PHONE && systemConfig_.uiType_ != UI_TYPE_PAD) {
9963 return;
9964 }
9965 TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9966 auto focusedSession = GetSceneSession(focusedSessionId_);
9967 // only when it's from a high zOrder to a low zOrder
9968 if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9969 focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9970 return;
9971 }
9972 auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9973 if (voiceInteractionSession == nullptr) {
9974 return;
9975 }
9976 TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9977 "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9978 voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9979 if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9980 focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9981 return;
9982 }
9983 RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9984 }
9985
PostProcessFocus()9986 void SceneSessionManager::PostProcessFocus()
9987 {
9988 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9989 // priority process focus requests from top to bottom
9990 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9991 {
9992 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9993 for (auto& iter : sceneSessionMap_) {
9994 auto session = iter.second;
9995 if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9996 continue;
9997 }
9998 processingSessions.push_back(iter);
9999 }
10000 }
10001 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
10002 bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
10003 !rhs.second->GetPostProcessFocusState().isFocused_;
10004 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
10005 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
10006 return focusCmp || lhsZOrder > rhsZOrder;
10007 };
10008 std::sort(processingSessions.begin(), processingSessions.end(), cmp);
10009
10010 // only change focus one time
10011 bool focusChanged = false;
10012 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
10013 auto session = iter->second;
10014 if (session == nullptr) {
10015 WLOGFE("session is nullptr");
10016 continue;
10017 }
10018 TLOGD(WmsLogTag::WMS_PIPELINE,
10019 "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
10020 session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
10021 session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
10022 if (focusChanged) {
10023 session->ResetPostProcessFocusState();
10024 continue;
10025 }
10026 WSError ret = WSError::WS_DO_NOTHING;
10027 if (session->GetPostProcessFocusState().isFocused_) {
10028 if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
10029 ret = RequestSessionFocusImmediately(session->GetPersistentId());
10030 } else {
10031 ret = RequestSessionFocus(session->GetPersistentId(), true,
10032 session->GetPostProcessFocusState().reason_);
10033 }
10034 } else {
10035 ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
10036 }
10037 session->ResetPostProcessFocusState();
10038 // if succeed then end process
10039 if (ret == WSError::WS_OK) {
10040 focusChanged = true;
10041 }
10042 }
10043 }
10044
PostProcessProperty(uint32_t dirty)10045 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
10046 {
10047 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
10048 if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
10049 // only trigger update avoid area
10050 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10051 for (auto& iter : sceneSessionMap_) {
10052 auto session = iter.second;
10053 if (session == nullptr) {
10054 continue;
10055 }
10056 session->PostProcessNotifyAvoidArea();
10057 }
10058 return;
10059 }
10060
10061 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
10062 {
10063 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10064 for (auto& iter : sceneSessionMap_) {
10065 auto session = iter.second;
10066 if (session == nullptr || !session->GetPostProcessProperty()) {
10067 continue;
10068 }
10069 processingSessions.push_back(iter);
10070 }
10071 }
10072
10073 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
10074 auto session = iter->second;
10075 if (session == nullptr) {
10076 WLOGFE("session is nullptr");
10077 continue;
10078 }
10079 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
10080 UpdateForceHideState(session, session->GetSessionProperty(), true);
10081 HandleKeepScreenOn(session, session->IsKeepScreenOn());
10082 UpdatePrivateStateAndNotify(session->GetPersistentId());
10083 if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10084 ProcessSubSessionForeground(session);
10085 }
10086 session->SetPostProcessProperty(false);
10087 }
10088
10089 // update avoid area
10090 {
10091 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10092 for (auto& iter : sceneSessionMap_) {
10093 auto session = iter.second;
10094 if (session == nullptr) {
10095 continue;
10096 }
10097 session->PostProcessNotifyAvoidArea();
10098 }
10099 }
10100 }
10101
10102 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)10103 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
10104 {
10105 WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
10106 auto isSaCall = SessionPermission::IsSACalling();
10107 if (!isSaCall) {
10108 WLOGFE("The interface only support for sa call");
10109 return WSError::WS_ERROR_INVALID_PERMISSION;
10110 }
10111 auto task = [this, persistentId]() {
10112 auto sceneSession = GetSceneSession(persistentId);
10113 if (sceneSession == nullptr) {
10114 WLOGFE("session is nullptr");
10115 return WSError::WS_ERROR_INVALID_SESSION;
10116 }
10117 if (!IsSessionVisibleForeground(sceneSession)) {
10118 WLOGFD("session is not visible!");
10119 return WSError::WS_DO_NOTHING;
10120 }
10121 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
10122 RequestSessionFocus(persistentId, true, reason);
10123 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
10124 sceneSession->RaiseToAppTop();
10125 }
10126 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
10127 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
10128 WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
10129 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
10130 }
10131 if (sceneSession == nullptr) {
10132 WLOGFE("parent session is nullptr");
10133 return WSError::WS_ERROR_INVALID_SESSION;
10134 }
10135 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10136 sceneSession->NotifyClick();
10137 return WSError::WS_OK;
10138 } else {
10139 WLOGFE("session is not app main window!");
10140 return WSError::WS_ERROR_INVALID_SESSION;
10141 }
10142 };
10143 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
10144 return WSError::WS_OK;
10145 }
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)10146 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
10147 {
10148 WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
10149 if (sourcePersistentId != focusedSessionId_) {
10150 WLOGFE("source session need be focused");
10151 return WSError::WS_ERROR_INVALID_OPERATION;
10152 }
10153 if (targetPersistentId == focusedSessionId_) {
10154 WLOGFE("target session has been focused");
10155 return WSError::WS_DO_NOTHING;
10156 }
10157 sptr<SceneSession> sourceSession = nullptr;
10158 WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
10159 if (ret != WSError::WS_OK) {
10160 return ret;
10161 }
10162 sptr<SceneSession> targetSession = nullptr;
10163 ret = GetAppMainSceneSession(targetSession, targetPersistentId);
10164 if (ret != WSError::WS_OK) {
10165 return ret;
10166 }
10167 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
10168 WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
10169 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
10170 return WSError::WS_ERROR_INVALID_CALLING;
10171 }
10172 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
10173 return WSError::WS_ERROR_INVALID_CALLING;
10174 }
10175 int32_t callingPid = IPCSkeleton::GetCallingPid();
10176 if (callingPid != targetSession->GetCallingPid()) {
10177 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
10178 return WSError::WS_ERROR_INVALID_CALLING;
10179 }
10180 targetSession->NotifyClick();
10181 FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
10182 return RequestSessionFocus(targetPersistentId, false, reason);
10183 }
10184
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)10185 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
10186 {
10187 sceneSession = GetSceneSession(persistentId);
10188 if (sceneSession == nullptr) {
10189 WLOGFE("session(%{public}d) is nullptr", persistentId);
10190 return WSError::WS_ERROR_INVALID_SESSION;
10191 }
10192 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10193 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
10194 WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
10195 return WSError::WS_ERROR_INVALID_CALLING;
10196 }
10197 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
10198 if (sceneSession == nullptr) {
10199 WLOGFE("session(%{public}d) parent is nullptr", persistentId);
10200 return WSError::WS_ERROR_INVALID_SESSION;
10201 }
10202 }
10203 return WSError::WS_OK;
10204 }
10205
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)10206 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
10207 const float scaleParam)
10208 {
10209 auto sceneSession = GetSceneSession(persistentId);
10210 if (!sceneSession) {
10211 WLOGFE("get scene session is nullptr");
10212 return nullptr;
10213 }
10214
10215 wptr<SceneSession> weakSceneSession(sceneSession);
10216 auto task = [this, persistentId, scaleParam, weakSceneSession]() {
10217 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
10218 auto scnSession = weakSceneSession.promote();
10219 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
10220 if (scnSession == nullptr) {
10221 WLOGFE("session is nullptr");
10222 return pixelMap;
10223 }
10224
10225 if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
10226 scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
10227 pixelMap = scnSession->Snapshot(false, scaleParam);
10228 }
10229 if (!pixelMap) {
10230 WLOGFI("get local snapshot pixelmap start");
10231 pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
10232 }
10233 return pixelMap;
10234 };
10235 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
10236 }
10237
GetSceneSessionMap()10238 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
10239 {
10240 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
10241 {
10242 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10243 retSceneSessionMap = sceneSessionMap_;
10244 }
10245 EraseIf(retSceneSessionMap, [this](const auto& pair) {
10246 if (pair.second == nullptr) {
10247 return true;
10248 }
10249
10250 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
10251 if (pair.second->IsVisible()) {
10252 return false;
10253 }
10254 return true;
10255 }
10256
10257 if (pair.second->IsSystemInput()) {
10258 return false;
10259 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
10260 return false;
10261 }
10262
10263 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
10264 return true;
10265 }
10266 return false;
10267 });
10268 return retSceneSessionMap;
10269 }
10270
NotifyUpdateRectAfterLayout()10271 void SceneSessionManager::NotifyUpdateRectAfterLayout()
10272 {
10273 auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
10274 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
10275 if (transactionController) {
10276 rsTransaction = transactionController->GetRSTransaction();
10277 }
10278 auto task = [this, rsTransaction]() {
10279 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10280 for (auto& iter: sceneSessionMap_) {
10281 auto sceneSession = iter.second;
10282 if (sceneSession && sceneSession->IsDirtyWindow()) {
10283 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
10284 }
10285 }
10286 };
10287 // need sync task since animation transcation need
10288 return taskScheduler_->PostAsyncTask(task);
10289 }
10290
GetAllWindowLayoutInfo(DisplayId displayId,std::vector<sptr<WindowLayoutInfo>> & infos)10291 WMError SceneSessionManager::GetAllWindowLayoutInfo(DisplayId displayId,
10292 std::vector<sptr<WindowLayoutInfo>>& infos)
10293 {
10294 auto task = [this, displayId, &infos]() mutable {
10295 constexpr bool isVirtualDisplay = false;
10296 std::vector<sptr<SceneSession>> filteredSessions;
10297 FilterForGetAllWindowLayoutInfo(displayId, isVirtualDisplay, filteredSessions);
10298 for (const auto& session : filteredSessions) {
10299 Rect globalScaledRect;
10300 session->GetGlobalScaledRect(globalScaledRect);
10301 auto windowLayoutInfo = sptr<WindowLayoutInfo>::MakeSptr();
10302 windowLayoutInfo->rect = globalScaledRect;
10303 infos.emplace_back(windowLayoutInfo);
10304 }
10305 return WMError::WM_OK;
10306 };
10307 return taskScheduler_->PostSyncTask(task, __func__);
10308 }
10309
FilterForGetAllWindowLayoutInfo(DisplayId displayId,bool isVirtualDisplay,std::vector<sptr<SceneSession>> & filteredSessions)10310 void SceneSessionManager::FilterForGetAllWindowLayoutInfo(DisplayId displayId, bool isVirtualDisplay,
10311 std::vector<sptr<SceneSession>>& filteredSessions)
10312 {
10313 {
10314 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10315 for (const auto& [_, session] : sceneSessionMap_) {
10316 if (session == nullptr) {
10317 continue;
10318 }
10319 if (session->GetSessionGlobalRect().IsInvalid()) {
10320 continue;
10321 }
10322 if (IsGetWindowLayoutInfoNeeded(session) && session->GetSessionProperty()->GetDisplayId() == displayId &&
10323 session->GetVisibilityState() != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
10324 filteredSessions.emplace_back(session);
10325 }
10326 }
10327 }
10328 std::sort(filteredSessions.begin(), filteredSessions.end(),
10329 [](const sptr<SceneSession>& lhs, const sptr<SceneSession>& rhs) {
10330 return lhs->GetZOrder() > rhs->GetZOrder();
10331 });
10332 }
10333
IsGetWindowLayoutInfoNeeded(const sptr<SceneSession> & session) const10334 bool SceneSessionManager::IsGetWindowLayoutInfoNeeded(const sptr<SceneSession>& session) const
10335 {
10336 constexpr int32_t GROUP_ONE = 1;
10337 std::string name = session->GetWindowName();
10338 std::regex pattern("^(.*?)(\\d*)$"); // Remove last digit
10339 std::smatch matches;
10340 name = std::regex_search(name, matches, pattern) ? matches[GROUP_ONE] : name;
10341 return !session->GetSessionInfo().isSystem_ || LAYOUT_INFO_WHITELIST.find(name) != LAYOUT_INFO_WHITELIST.end();
10342 }
10343
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)10344 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
10345 {
10346 if (!SessionPermission::IsSystemCalling()) {
10347 WLOGFE("GetVisibilityWindowInfo permission denied!");
10348 return WMError::WM_ERROR_NOT_SYSTEM_APP;
10349 }
10350 auto task = [this, &infos]() {
10351 for (auto [surfaceId, _] : lastVisibleData_) {
10352 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
10353 if (session == nullptr) {
10354 continue;
10355 }
10356 WSRect hostRect = session->GetSessionRect();
10357 Rect rect = {hostRect.posX_, hostRect.posY_,
10358 static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
10359 auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
10360 session->GetSessionProperty());
10361 infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
10362 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
10363 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
10364 session->IsFocused()));
10365 }
10366 return WMError::WM_OK;
10367 };
10368 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
10369 }
10370
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)10371 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
10372 {
10373 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10374 for (const auto& [id, session] : sceneSessionMap_) {
10375 if (session == nullptr) {
10376 continue;
10377 }
10378 uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
10379 windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
10380 }
10381 }
10382
FlushWindowInfoToMMI(const bool forceFlush)10383 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
10384 {
10385 auto task = [this, forceFlush] {
10386 if (isUserBackground_) {
10387 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
10388 return;
10389 }
10390 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
10391 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
10392 };
10393 taskScheduler_->PostAsyncTask(task);
10394 }
10395
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)10396 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
10397 int32_t& parentId)
10398 {
10399 // This function should be called in task
10400 auto iter = extSessionInfoMap_.find(token);
10401 if (iter == extSessionInfoMap_.end()) {
10402 return false;
10403 }
10404 persistentId = iter->second.persistentId;
10405 parentId = iter->second.parentId;
10406 return true;
10407 }
10408
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession,bool isConstrainedModal)10409 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession, bool isConstrainedModal)
10410 {
10411 auto task = [this, remoteExtSession, isConstrainedModal]() {
10412 auto iter = remoteExtSessionMap_.find(remoteExtSession);
10413 if (iter == remoteExtSessionMap_.end()) {
10414 TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
10415 return;
10416 }
10417 auto abilityToken = iter->second;
10418 int32_t persistentId = INVALID_SESSION_ID;
10419 int32_t parentId = INVALID_SESSION_ID;
10420 if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
10421 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10422 return;
10423 }
10424
10425 TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
10426 persistentId, parentId);
10427 auto sceneSession = GetSceneSession(parentId);
10428 if (sceneSession != nullptr) {
10429 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10430 sceneSession->RemoveExtWindowFlags(persistentId);
10431 if (oldFlags.hideNonSecureWindowsFlag) {
10432 HandleSecureSessionShouldHide(sceneSession);
10433 }
10434 if (oldFlags.waterMarkFlag) {
10435 CheckAndNotifyWaterMarkChangedResult();
10436 }
10437 if (oldFlags.privacyModeFlag) {
10438 UpdatePrivateStateAndNotify(parentId);
10439 }
10440 if (!isConstrainedModal) {
10441 sceneSession->RemoveNormalModalUIExtension(persistentId);
10442 }
10443 sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
10444 sceneSession->RemoveExtensionTokenInfo(abilityToken);
10445 } else {
10446 ExtensionWindowFlags actions;
10447 actions.SetAllActive();
10448 HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
10449 }
10450 extSessionInfoMap_.erase(iter->second);
10451 remoteExtSessionMap_.erase(iter);
10452 };
10453 taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
10454 }
10455
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)10456 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
10457 {
10458 auto pid = IPCSkeleton::GetCallingRealPid();
10459 auto task = [this, token, pid, rect]() {
10460 int32_t persistentId = INVALID_SESSION_ID;
10461 int32_t parentId = INVALID_SESSION_ID;
10462 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10463 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10464 return;
10465 }
10466 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
10467 "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
10468 pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10469 auto parentSession = GetSceneSession(parentId);
10470 if (parentSession) {
10471 auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
10472 auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
10473 Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
10474 ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
10475 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
10476 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
10477 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
10478 parentSession->GetSessionGlobalRect().ToString().c_str());
10479 parentSession->UpdateNormalModalUIExtension(extensionInfo);
10480 }
10481 };
10482 taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
10483 }
10484
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)10485 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
10486 {
10487 auto pid = IPCSkeleton::GetCallingRealPid();
10488 auto task = [this, token, pid, posX, posY]() {
10489 int32_t persistentId = INVALID_SESSION_ID;
10490 int32_t parentId = INVALID_SESSION_ID;
10491 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10492 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10493 return;
10494 }
10495 TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
10496 "parentId=%{public}d", pid, persistentId, parentId);
10497 auto parentSession = GetSceneSession(parentId);
10498 if (parentSession) {
10499 auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
10500 if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
10501 modalUIExtensionEventInfo.value().persistentId == persistentId) {
10502 parentSession->ProcessPointDownSession(posX, posY);
10503 }
10504 }
10505 };
10506 taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
10507 }
10508
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId,bool isConstrainedModal)10509 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
10510 const sptr<IRemoteObject>& token, uint64_t surfaceNodeId, bool isConstrainedModal)
10511 {
10512 auto pid = IPCSkeleton::GetCallingRealPid();
10513 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
10514 auto task = [this, sessionStage, token, surfaceNodeId, isConstrainedModal, pid, callingTokenId]() {
10515 if (sessionStage == nullptr || token == nullptr) {
10516 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10517 return;
10518 }
10519 auto remoteExtSession = sessionStage->AsObject();
10520 if (remoteExtSession == nullptr) {
10521 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10522 return;
10523 }
10524 if (extensionDeath_ == nullptr) {
10525 TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
10526 return;
10527 }
10528 if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
10529 TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
10530 return;
10531 }
10532
10533 AAFwk::UIExtensionSessionInfo info;
10534 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
10535 if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
10536 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
10537 return;
10538 }
10539
10540 int32_t persistentId = info.persistentId;
10541 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
10542 UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
10543 TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
10544 "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
10545 surfaceNodeId, pid);
10546
10547 remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
10548 extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
10549
10550 auto parentSession = GetSceneSession(parentId);
10551 if (!parentSession) {
10552 TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
10553 return;
10554 }
10555
10556 UIExtensionTokenInfo tokenInfo;
10557 tokenInfo.abilityToken = token;
10558 tokenInfo.callingTokenId = callingTokenId;
10559 tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
10560 info.extensionAbilityType);
10561 parentSession->AddExtensionTokenInfo(tokenInfo);
10562 parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
10563 if (usage == UIExtensionUsage::MODAL) {
10564 ExtensionWindowEventInfo extensionInfo {
10565 .persistentId = persistentId,
10566 .pid = pid,
10567 };
10568 if (!isConstrainedModal) {
10569 parentSession->AddNormalModalUIExtension(extensionInfo);
10570 }
10571 }
10572 };
10573 taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
10574 }
10575
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,bool isConstrainedModal)10576 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
10577 const sptr<IRemoteObject>& token, bool isConstrainedModal)
10578 {
10579 TLOGI(WmsLogTag::WMS_UIEXT, "in");
10580 auto task = [this, sessionStage, token, isConstrainedModal]() {
10581 if (sessionStage == nullptr || token == nullptr) {
10582 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10583 return;
10584 }
10585 auto remoteExtSession = sessionStage->AsObject();
10586 if (remoteExtSession == nullptr) {
10587 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10588 return;
10589 }
10590 auto iter = remoteExtSessionMap_.find(remoteExtSession);
10591 if (iter == remoteExtSessionMap_.end() || iter->second != token) {
10592 TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
10593 return;
10594 }
10595
10596 DestroyExtensionSession(remoteExtSession, isConstrainedModal);
10597 };
10598 taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
10599 }
10600
CalculateCombinedExtWindowFlags()10601 void SceneSessionManager::CalculateCombinedExtWindowFlags()
10602 {
10603 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
10604 combinedExtWindowFlags_.bitData = 0;
10605 for (const auto& iter: extWindowFlagsMap_) {
10606 combinedExtWindowFlags_.bitData |= iter.second.bitData;
10607 }
10608 specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
10609 }
10610
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10611 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
10612 ExtensionWindowFlags actions)
10613 {
10614 auto iter = extWindowFlagsMap_.find(persistentId);
10615 // Each flag is false when inactive, 0 means all flags are inactive
10616 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
10617 ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
10618 if (newFlags.bitData == 0) {
10619 extWindowFlagsMap_.erase(persistentId);
10620 } else {
10621 extWindowFlagsMap_[persistentId] = newFlags;
10622 }
10623 CalculateCombinedExtWindowFlags();
10624 }
10625
HideNonSecureFloatingWindows()10626 void SceneSessionManager::HideNonSecureFloatingWindows()
10627 {
10628 bool shouldHide = false;
10629 {
10630 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10631 for (const auto& iter: sceneSessionMap_) {
10632 auto& session = iter.second;
10633 if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
10634 shouldHide = true;
10635 break;
10636 }
10637 }
10638 }
10639 if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
10640 TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
10641 shouldHide = true;
10642 }
10643 if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
10644 return;
10645 }
10646
10647 shouldHideNonSecureFloatingWindows_.store(shouldHide);
10648 for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
10649 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
10650 session->NotifyForceHideChange(shouldHide);
10651 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10652 session->GetWindowName().c_str(), persistentId, shouldHide);
10653 }
10654 }
10655 }
10656
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)10657 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
10658 {
10659 // don't let sub-window show when switching secure host window to background
10660 if (!sceneSession->IsSessionForeground()) {
10661 return;
10662 }
10663
10664 auto parentId = sceneSession->GetPersistentId();
10665 bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
10666 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10667 for (const auto& [persistentId, session] : sceneSessionMap_) {
10668 if (!session) {
10669 continue;
10670 }
10671 auto property = session->GetSessionProperty();
10672 if (!property || property->GetParentPersistentId() != parentId) {
10673 continue;
10674 }
10675
10676 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
10677 session->NotifyForceHideChange(shouldHide);
10678 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10679 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
10680 }
10681 }
10682 }
10683
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)10684 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
10685 {
10686 if (sceneSession == nullptr) {
10687 TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
10688 return WSError::WS_ERROR_INVALID_SESSION;
10689 }
10690
10691 HideNonSecureFloatingWindows();
10692 HideNonSecureSubWindows(sceneSession);
10693 return WSError::WS_OK;
10694 }
10695
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10696 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
10697 ExtensionWindowFlags actions)
10698 {
10699 UpdateSpecialExtWindowFlags(persistentId, flags, actions);
10700 if (actions.waterMarkFlag) {
10701 CheckAndNotifyWaterMarkChangedResult();
10702 }
10703 if (actions.hideNonSecureWindowsFlag) {
10704 HideNonSecureFloatingWindows();
10705 }
10706 if (actions.privacyModeFlag) {
10707 UpdatePrivateStateAndNotifyForAllScreens();
10708 }
10709 }
10710
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)10711 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
10712 {
10713 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
10714 if (!SessionPermission::IsSystemCalling()) {
10715 TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
10716 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10717 }
10718 const auto callingPid = IPCSkeleton::GetCallingRealPid();
10719 auto task = [this, persistentId, shouldHide, callingPid]() {
10720 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10721 auto iter = sceneSessionMap_.find(persistentId);
10722 if (iter == sceneSessionMap_.end()) {
10723 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
10724 persistentId);
10725 return WSError::WS_ERROR_INVALID_SESSION;
10726 }
10727 auto sceneSession = iter->second;
10728 if (sceneSession == nullptr) {
10729 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
10730 return WSError::WS_ERROR_NULLPTR;
10731 }
10732 if (callingPid != sceneSession->GetCallingPid()) {
10733 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
10734 return WSError::WS_ERROR_INVALID_PERMISSION;
10735 }
10736 sceneSession->SetShouldHideNonSecureWindows(shouldHide);
10737 return HandleSecureSessionShouldHide(sceneSession);
10738 };
10739
10740 taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
10741 return WSError::WS_OK;
10742 }
10743
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const10744 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
10745 {
10746 auto ret = WSError::WS_OK;
10747 bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
10748 if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
10749 actions.hideNonSecureWindowsFlag = false;
10750 actions.waterMarkFlag = false;
10751 TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
10752 ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
10753 }
10754 auto needPrivacyWindow = actions.privacyModeFlag;
10755 if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
10756 actions.privacyModeFlag = false;
10757 TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
10758 ret = WSError::WS_ERROR_INVALID_PERMISSION;
10759 }
10760 return ret;
10761 }
10762
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)10763 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
10764 uint32_t extWindowActions)
10765 {
10766 ExtensionWindowFlags actions(extWindowActions);
10767 auto ret = CheckExtWindowFlagsPermission(actions);
10768 if (actions.bitData == 0) {
10769 return ret;
10770 }
10771
10772 ExtensionWindowFlags flags(extWindowFlags);
10773 auto task = [this, token, flags, actions]() {
10774 int32_t persistentId = INVALID_SESSION_ID;
10775 int32_t parentId = INVALID_SESSION_ID;
10776 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10777 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10778 return WSError::WS_ERROR_INVALID_OPERATION;
10779 }
10780
10781 TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
10782 "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
10783 auto sceneSession = GetSceneSession(parentId);
10784 if (sceneSession == nullptr) {
10785 TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
10786 parentId);
10787 HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
10788 return WSError::WS_OK;
10789 }
10790
10791 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10792 sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
10793 auto newFlags = sceneSession->GetCombinedExtWindowFlags();
10794 if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
10795 HandleSecureSessionShouldHide(sceneSession);
10796 }
10797 if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
10798 CheckAndNotifyWaterMarkChangedResult();
10799 }
10800 if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
10801 UpdatePrivateStateAndNotify(parentId);
10802 }
10803 return WSError::WS_OK;
10804 };
10805
10806 taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
10807 return ret;
10808 }
10809
GetHostWindowRect(int32_t hostWindowId,Rect & rect)10810 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
10811 {
10812 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
10813 if (!SessionPermission::IsSystemCalling()) {
10814 TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
10815 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10816 }
10817 auto task = [this, hostWindowId, &rect]() {
10818 auto sceneSession = GetSceneSession(hostWindowId);
10819 if (sceneSession == nullptr) {
10820 TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
10821 return WSError::WS_ERROR_INVALID_SESSION;
10822 }
10823 WSRect hostRect = sceneSession->GetSessionRect();
10824 rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
10825 return WSError::WS_OK;
10826 };
10827 taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
10828 return WSError::WS_OK;
10829 }
10830
ReclaimPurgeableCleanMem()10831 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
10832 {
10833 #ifdef MEMMGR_WINDOW_ENABLE
10834 return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
10835 #else
10836 return -1;
10837 #endif
10838 }
10839
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)10840 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
10841 const std::vector<VisibleWindowNumInfo>& currentInfo)
10842 {
10843 if (lastInfo.size() != currentInfo.size()) {
10844 WLOGFE("last and current info is not Same");
10845 return false;
10846 }
10847 int sizeOfLastInfo = static_cast<int>(lastInfo.size());
10848 for (int i = 0; i < sizeOfLastInfo; i++) {
10849 if (lastInfo[i].displayId != currentInfo[i].displayId ||
10850 lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
10851 WLOGFE("last and current visible window num is not Same");
10852 return false;
10853 }
10854 }
10855 return true;
10856 }
10857
CacVisibleWindowNum()10858 void SceneSessionManager::CacVisibleWindowNum()
10859 {
10860 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10861 {
10862 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10863 sceneSessionMapCopy = sceneSessionMap_;
10864 }
10865 std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
10866 bool isFullScreen = true;
10867 for (const auto& elem : sceneSessionMapCopy) {
10868 auto curSession = elem.second;
10869 if (curSession == nullptr) {
10870 continue;
10871 }
10872 bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
10873 curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
10874 if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10875 continue;
10876 }
10877
10878 bool isWindowVisible = curSession->GetRSVisible();
10879 if (isWindowVisible) {
10880 auto windowMode = curSession->GetWindowMode();
10881 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
10882 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
10883 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
10884 isFullScreen = false;
10885 }
10886 int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
10887 auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10888 [=](const VisibleWindowNumInfo& info) {
10889 return (static_cast<int32_t>(info.displayId)) == displayId;
10890 });
10891 if (it == visibleWindowNumInfo.end()) {
10892 visibleWindowNumInfo.push_back({displayId, 1});
10893 } else {
10894 it->visibleWindowNum++;
10895 }
10896 }
10897 }
10898 if (isFullScreen) {
10899 std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10900 [](auto& info) { info.visibleWindowNum = 1; });
10901 }
10902 std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
10903 if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10904 SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10905 lastInfo_ = visibleWindowNumInfo;
10906 }
10907 }
10908
ReportWindowProfileInfos()10909 void SceneSessionManager::ReportWindowProfileInfos()
10910 {
10911 enum class WindowVisibleState : int32_t {
10912 FOCUSBLE = 0,
10913 VISIBLE,
10914 MINIMIZED,
10915 OCCLUSION
10916 };
10917 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10918 {
10919 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10920 sceneSessionMapCopy = sceneSessionMap_;
10921 }
10922 auto focusWindowId = GetFocusedSessionId();
10923 for (const auto& elem : sceneSessionMapCopy) {
10924 auto curSession = elem.second;
10925 if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10926 curSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10927 continue;
10928 }
10929 WindowProfileInfo windowProfileInfo;
10930 windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10931 windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10932 curSession->GetSessionProperty()->GetDisplayId());
10933 windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10934 if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10935 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10936 } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10937 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10938 } else if (!curSession->GetRSVisible()) {
10939 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10940 } else {
10941 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10942 }
10943 WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10944 WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10945 "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10946 windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10947 windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10948 }
10949 }
10950
GetCustomDecorHeight(int32_t persistentId)10951 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10952 {
10953 int32_t height = 0;
10954 auto sceneSession = GetSceneSession(persistentId);
10955 if (sceneSession == nullptr) {
10956 TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10957 return 0;
10958 }
10959 height = sceneSession->GetCustomDecorHeight();
10960 TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10961 return height;
10962 }
10963
RemoveFailRecoveredSession()10964 void SceneSessionManager::RemoveFailRecoveredSession()
10965 {
10966 for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10967 auto sceneSession = GetSceneSession(persistentId);
10968 if (sceneSession == nullptr) {
10969 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10970 continue;
10971 }
10972 if (!sceneSession->IsRecovered()) {
10973 TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10974 continue;
10975 }
10976 const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10977 if (!scnSessionInfo) {
10978 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr,persistentId = %{public}d", persistentId);
10979 continue;
10980 }
10981 TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10982 sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10983 }
10984 failRecoveredPersistentIdSet_.clear();
10985 }
10986
GetDisplayRegion(DisplayId displayId)10987 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10988 {
10989 if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10990 return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10991 }
10992 TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10993 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10994 if (display == nullptr) {
10995 TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10996 return nullptr;
10997 }
10998 auto displayInfo = display->GetDisplayInfo();
10999 if (displayInfo == nullptr) {
11000 TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
11001 return nullptr;
11002 }
11003 int32_t displayWidth = displayInfo->GetWidth();
11004 int32_t displayHeight = displayInfo->GetHeight();
11005 if (displayWidth == 0 || displayHeight == 0) {
11006 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
11007 return nullptr;
11008 }
11009
11010 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
11011 auto region = std::make_shared<SkRegion>(rect);
11012 displayRegionMap_[displayId] = region;
11013 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
11014 return std::make_shared<SkRegion>(rect);
11015 }
11016
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)11017 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
11018 {
11019 if (displayInfo == nullptr) {
11020 TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
11021 return;
11022 }
11023 auto displayId = displayInfo->GetDisplayId();
11024 int32_t displayWidth = displayInfo->GetWidth();
11025 int32_t displayHeight = displayInfo->GetHeight();
11026 if (displayWidth == 0 || displayHeight == 0) {
11027 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
11028 return;
11029 }
11030 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
11031 auto region = std::make_shared<SkRegion>(rect);
11032 displayRegionMap_[displayId] = region;
11033 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
11034 }
11035
GetDisplaySizeById(DisplayId displayId,int32_t & displayWidth,int32_t & displayHeight)11036 bool SceneSessionManager::GetDisplaySizeById(DisplayId displayId, int32_t& displayWidth, int32_t& displayHeight)
11037 {
11038 auto region = GetDisplayRegion(displayId);
11039 if (region == nullptr) {
11040 TLOGW(WmsLogTag::WMS_LAYOUT, "failed, displayId:%{public}" PRIu64, displayId);
11041 return false;
11042 }
11043 const SkIRect& rect = region->getBounds();
11044 displayWidth = rect.fRight;
11045 displayHeight = rect.fBottom;
11046 return true;
11047 }
11048
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)11049 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
11050 {
11051 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11052 for (const auto& item : sceneSessionMap_) {
11053 auto sceneSession = item.second;
11054 if (sceneSession == nullptr) {
11055 continue;
11056 }
11057 if (Session::IsScbCoreEnabled()) {
11058 if (!sceneSession->IsVisibleForAccessibility()) {
11059 continue;
11060 }
11061 } else {
11062 if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
11063 continue;
11064 }
11065 }
11066 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
11067 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
11068 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
11069 continue;
11070 }
11071 sceneSessionList.push_back(sceneSession);
11072 }
11073 }
11074
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)11075 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
11076 std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
11077 {
11078 for (const auto& sceneSession : sceneSessionList) {
11079 if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
11080 TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
11081 }
11082 }
11083 }
11084
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)11085 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
11086 {
11087 std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
11088 return a->GetZOrder() > b->GetZOrder();
11089 });
11090 std::vector<sptr<SceneSession>> result;
11091 std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
11092 for (const auto& sceneSession : sceneSessionList) {
11093 if (sceneSession == nullptr) {
11094 TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
11095 continue;
11096 }
11097 auto sessionProperty = sceneSession->GetSessionProperty();
11098 if (sessionProperty == nullptr) {
11099 TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
11100 continue;
11101 }
11102 std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
11103 auto displayId = sessionProperty->GetDisplayId();
11104 if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
11105 unaccountedSpace = unaccountedSpaceMap[displayId];
11106 } else {
11107 unaccountedSpace = GetDisplayRegion(displayId);
11108 if (unaccountedSpace == nullptr) {
11109 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
11110 continue;
11111 }
11112 unaccountedSpaceMap[displayId] = unaccountedSpace;
11113 }
11114 WSRect wsRect = sceneSession->GetSessionRect();
11115 SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
11116 .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
11117 SkRegion windowRegion(windowBounds);
11118 if (unaccountedSpace->quickReject(windowRegion)) {
11119 TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
11120 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
11121 continue;
11122 }
11123 if (!unaccountedSpace->intersects(windowRegion)) {
11124 TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
11125 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
11126 continue;
11127 }
11128 result.push_back(sceneSession);
11129 unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
11130 if (unaccountedSpace->isEmpty()) {
11131 break;
11132 }
11133 }
11134 sceneSessionList = result;
11135 }
11136
NotifyAllAccessibilityInfo()11137 void SceneSessionManager::NotifyAllAccessibilityInfo()
11138 {
11139 if (isUserBackground_) {
11140 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
11141 return;
11142 }
11143 std::vector<sptr<SceneSession>> sceneSessionList;
11144 GetAllSceneSessionForAccessibility(sceneSessionList);
11145 FilterSceneSessionCovered(sceneSessionList);
11146
11147 std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
11148 FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
11149
11150 for (const auto& item : accessibilityInfo) {
11151 TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, \
11152 bundle=%{public}s, bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
11153 item->wid_, item->innerWid_, item->bundleName_.c_str(),
11154 item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
11155 for (const auto& rect : item->touchHotAreas_) {
11156 TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d," \
11157 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
11158 }
11159 }
11160
11161 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
11162 WindowUpdateType::WINDOW_UPDATE_ALL);
11163 }
11164
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)11165 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
11166 const sptr<WindowSessionProperty>& property)
11167 {
11168 auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
11169 if (property == nullptr) {
11170 return windowStatus;
11171 }
11172 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
11173 windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
11174 if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
11175 windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
11176 }
11177 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
11178 windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
11179 } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
11180 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
11181 } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
11182 windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
11183 }
11184 return windowStatus;
11185 }
11186
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)11187 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
11188 {
11189 if (!SessionPermission::IsStartedByInputMethod()) {
11190 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
11191 return WMError::WM_ERROR_INVALID_PERMISSION;
11192 }
11193 auto scnSession = GetSceneSession(persistentId);
11194 if (scnSession == nullptr) {
11195 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
11196 return WMError::WM_ERROR_NULLPTR;
11197 }
11198
11199 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
11200 persistentId, scnSession->GetWindowType());
11201
11202 auto sessionProperty = scnSession->GetSessionProperty();
11203 if (sessionProperty == nullptr) {
11204 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
11205 return WMError::WM_ERROR_INVALID_WINDOW;
11206 }
11207 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
11208 auto callingSession = GetSceneSession(callingWindowId);
11209 if (callingSession == nullptr) {
11210 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
11211 callingSession = GetSceneSession(focusedSessionId_);
11212 if (callingSession == nullptr) {
11213 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
11214 return WMError::WM_ERROR_INVALID_WINDOW;
11215 }
11216 }
11217 if (callingSession->IsSystemSession()) {
11218 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
11219 } else {
11220 windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
11221 callingSession->GetSessionProperty());
11222 }
11223 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
11224 persistentId, windowStatus);
11225 return WMError::WM_OK;
11226 }
11227
GetCallingWindowRect(int32_t persistentId,Rect & rect)11228 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
11229 {
11230 if (!SessionPermission::IsStartedByInputMethod()) {
11231 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
11232 return WMError::WM_ERROR_INVALID_PERMISSION;
11233 }
11234 auto scnSession = GetSceneSession(persistentId);
11235 if (scnSession == nullptr) {
11236 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
11237 return WMError::WM_ERROR_NULLPTR;
11238 }
11239 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
11240 persistentId, scnSession->GetWindowType());
11241 auto sessionProperty = scnSession->GetSessionProperty();
11242 if (sessionProperty == nullptr) {
11243 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
11244 return WMError::WM_ERROR_INVALID_WINDOW;
11245 }
11246 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
11247 auto callingSession = GetSceneSession(callingWindowId);
11248 if (callingSession == nullptr) {
11249 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
11250 callingSession = GetSceneSession(focusedSessionId_);
11251 if (callingSession == nullptr) {
11252 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
11253 return WMError::WM_ERROR_INVALID_WINDOW;
11254 }
11255 }
11256 WSRect sessionRect = callingSession->GetSessionRect();
11257 rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
11258 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
11259 "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
11260 return WMError::WM_OK;
11261 }
11262
GetWindowModeType(WindowModeType & windowModeType)11263 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
11264 {
11265 if (!SessionPermission::IsSACalling()) {
11266 WLOGFE("GetWindowModeType permission denied!");
11267 return WMError::WM_ERROR_INVALID_PERMISSION;
11268 }
11269 windowModeType = CheckWindowModeType();
11270 return WMError::WM_OK;
11271 }
11272
GetWindowStyleType(WindowStyleType & windowStyleType)11273 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
11274 {
11275 if (!SessionPermission::IsSACalling()) {
11276 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
11277 return WMError::WM_ERROR_INVALID_PERMISSION;
11278 }
11279 auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
11280 if (isPC) {
11281 windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
11282 return WMError::WM_OK;
11283 }
11284 windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
11285 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
11286 return WMError::WM_OK;
11287 }
11288
CheckSceneZOrder()11289 void SceneSessionManager::CheckSceneZOrder()
11290 {
11291 auto task = [this]() {
11292 AnomalyDetection::SceneZOrderCheckProcess();
11293 };
11294 taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
11295 }
11296
NotifyEnterRecentTask(bool enterRecent)11297 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
11298 {
11299 TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
11300 enterRecent_.store(enterRecent);
11301 SetSystemAnimatedScenes(enterRecent ?
11302 SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
11303 auto task = [this] {
11304 for (auto persistentId : gestureBackEnableWindowIdSet_) {
11305 auto sceneSession = GetSceneSession(persistentId);
11306 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
11307 continue;
11308 }
11309 UpdateGestureBackEnabled(persistentId);
11310 }
11311 };
11312 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
11313 return WSError::WS_OK;
11314 }
11315
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)11316 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
11317 {
11318 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
11319 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11320 return WMError::WM_ERROR_INVALID_PERMISSION;
11321 }
11322
11323 if (!topNInfo.empty() || (topNum <= 0)) {
11324 return WMError::WM_ERROR_INVALID_PARAM;
11325 }
11326
11327 TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
11328 auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
11329 if (session == nullptr) {
11330 return false;
11331 }
11332
11333 if (topNum == 0) {
11334 return true;
11335 }
11336
11337 if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
11338 TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
11339 return false;
11340 }
11341
11342 MainWindowInfo info;
11343 info.pid_ = session->GetCallingPid();
11344 info.bundleName_ = session->GetSessionInfo().bundleName_;
11345 topNInfo.push_back(info);
11346 topNum--;
11347 TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
11348 topNum, info.pid_, info.bundleName_.c_str());
11349 return false;
11350 };
11351 TraverseSessionTree(func, true);
11352
11353 return WMError::WM_OK;
11354 }
11355
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)11356 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
11357 int32_t x, int32_t y, std::vector<int32_t>& windowIds)
11358 {
11359 TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
11360 displayId, windowNumber, x, y);
11361 if (displayId == DISPLAY_ID_INVALID) {
11362 TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
11363 return WMError::WM_ERROR_INVALID_PARAM;
11364 }
11365 bool findAllWindow = windowNumber <= 0;
11366 bool checkPoint = (x >= 0 && y >= 0);
11367 std::string callerBundleName = SessionPermission::GetCallingBundleName();
11368 auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
11369 findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
11370 if (session == nullptr) {
11371 return false;
11372 }
11373 auto sessionProperty = session->GetSessionProperty();
11374 if (sessionProperty == nullptr) {
11375 return false;
11376 }
11377 if (!findAllWindow && windowNumber == 0) {
11378 return true;
11379 }
11380 bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
11381 bool isSameDisplayId = sessionProperty->GetDisplayId() == displayId;
11382 bool isRsVisible = session->GetRSVisible();
11383 WSRect windowRect = session->GetSessionRect();
11384 bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
11385 TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
11386 " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
11387 session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
11388 sessionProperty->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
11389 if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
11390 return false;
11391 }
11392 windowIds.emplace_back(session->GetPersistentId());
11393 windowNumber--;
11394 return false;
11395 };
11396 auto task = [this, func = std::move(func)] {
11397 TraverseSessionTree(func, true);
11398 return WMError::WM_OK;
11399 };
11400 return taskScheduler_->PostSyncTask(task, __func__);
11401 }
11402
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const11403 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
11404 {
11405 if (!infos.empty()) {
11406 TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
11407 return WMError::WM_ERROR_INVALID_PARAM;
11408 }
11409 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11410 TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
11411 return WMError::WM_ERROR_INVALID_PERMISSION;
11412 }
11413 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11414 for (const auto& iter : sceneSessionMap_) {
11415 auto& session = iter.second;
11416 if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
11417 continue;
11418 }
11419 MainWindowInfo info;
11420 auto abilityInfo = session->GetSessionInfo().abilityInfo;
11421 info.pid_ = session->GetCallingPid();
11422 info.bundleName_ = session->GetSessionInfo().bundleName_;
11423 info.persistentId_ = session->GetPersistentId();
11424 if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
11425 TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
11426 info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
11427 infos.push_back(info);
11428 } else if (abilityInfo != nullptr) {
11429 info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
11430 infos.push_back(info);
11431 TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
11432 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
11433 info.bundleName_.c_str(), info.bundleType_);
11434 }
11435 }
11436 return WMError::WM_OK;
11437 }
11438
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)11439 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
11440 std::vector<int32_t>& clearFailedIds)
11441 {
11442 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11443 TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
11444 return WMError::WM_ERROR_INVALID_PERMISSION;
11445 }
11446 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
11447 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
11448 return WMError::WM_ERROR_INVALID_PERMISSION;
11449 }
11450 clearFailedIds.clear();
11451 for (const auto persistentId : persistentIds) {
11452 auto sceneSession = GetSceneSession(persistentId);
11453 if (sceneSession == nullptr) {
11454 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
11455 clearFailedIds.push_back(persistentId);
11456 continue;
11457 }
11458 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11459 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11460 clearFailedIds.push_back(persistentId);
11461 continue;
11462 }
11463 sceneSession->Clear();
11464 TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
11465 }
11466 return WMError::WM_OK;
11467 }
11468
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)11469 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
11470 bool enable)
11471 {
11472 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
11473 width, height, density, enable);
11474
11475 DMHookInfo dmHookInfo;
11476 dmHookInfo.width_ = width;
11477 dmHookInfo.height_ = height;
11478 dmHookInfo.density_ = density;
11479 dmHookInfo.rotation_ = 0;
11480 dmHookInfo.enableHookRotation_ = false;
11481 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11482 return WMError::WM_OK;
11483 }
11484
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)11485 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
11486 {
11487 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
11488 "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
11489 hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
11490
11491 DMHookInfo dmHookInfo;
11492 dmHookInfo.width_ = hookInfo.width_;
11493 dmHookInfo.height_ = hookInfo.height_;
11494 dmHookInfo.density_ = hookInfo.density_;
11495 dmHookInfo.rotation_ = hookInfo.rotation_;
11496 dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
11497 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11498 return WMError::WM_OK;
11499 }
11500
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)11501 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
11502 {
11503 SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
11504 }
11505
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)11506 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
11507 {
11508 ScreenFoldData screenFoldData;
11509 WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
11510 if (ret != WMError::WM_OK) {
11511 return ret;
11512 }
11513 return CheckAndReportScreenFoldStatus(screenFoldData);
11514 }
11515
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)11516 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
11517 ScreenFoldData& screenFoldData)
11518 {
11519 if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
11520 TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
11521 return WMError::WM_DO_NOTHING;
11522 }
11523
11524 screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
11525 screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
11526 screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
11527 screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
11528 screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
11529 if (!screenFoldData.GetTypeCThermalWithUtil()) {
11530 TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
11531 return WMError::WM_DO_NOTHING;
11532 }
11533 AppExecFwk::ElementName element = {};
11534 WSError ret = GetFocusSessionElement(element);
11535 if (ret != WSError::WS_OK) {
11536 TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
11537 return WMError::WM_DO_NOTHING;
11538 }
11539 screenFoldData.SetFocusedPkgName(element.GetURI());
11540 return WMError::WM_OK;
11541 }
11542
CheckAndReportScreenFoldStatus(ScreenFoldData & data)11543 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
11544 {
11545 static ScreenFoldData lastScreenHalfFoldData;
11546 if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11547 lastScreenHalfFoldData = data;
11548 return WMError::WM_DO_NOTHING;
11549 }
11550 WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
11551 if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11552 if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
11553 lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
11554 } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
11555 // if stay at half-fold less than 15s, combine this change with last
11556 data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
11557 data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
11558 data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
11559 }
11560 lastScreenHalfFoldData.SetInvalid();
11561 }
11562 WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
11563 return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
11564 currentScreenFoldStatusReportRet;
11565 }
11566
11567 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)11568 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
11569 {
11570 if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
11571 return WMError::WM_DO_NOTHING;
11572 }
11573
11574 int32_t ret = HiSysEventWrite(
11575 OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
11576 "FOLDSCREEN_STATE_CHANGE",
11577 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
11578 "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
11579 "LASTFOLDSTATE", data.currentScreenFoldStatus_,
11580 "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
11581 "STATE", -1,
11582 "TIME", data.currentScreenFoldStatusDuration_,
11583 "ROTATION", data.screenRotation_,
11584 "PACKAGE", data.focusedPackageName_,
11585 "ANGLE", data.postureAngle_,
11586 "TYPECTHERMAL", data.typeCThermal_,
11587 "SCREENTHERMAL", -1,
11588 "SCANGLE", -1,
11589 "ISTENT", -1);
11590 if (ret != 0) {
11591 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
11592 return WMError::WM_DO_NOTHING;
11593 }
11594 return WMError::WM_OK;
11595 }
11596
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userid)11597 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
11598 {
11599 if (currentUserId_ != static_cast<int32_t>(userid)) {
11600 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64,
11601 currentUserId_.load(), userid);
11602 return;
11603 }
11604 if (secExtensionData == nullptr) {
11605 TLOGE(WmsLogTag::WMS_EVENT, "invalid secExtensionData");
11606 return;
11607 }
11608 auto secSurfaceInfoMap = secExtensionData->GetSecData();
11609 auto task = [secSurfaceInfoMap]()-> WSError {
11610 SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
11611 return WSError::WS_OK;
11612 };
11613 taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
11614 }
11615
RegisterSecSurfaceInfoListener()11616 void SceneSessionManager::RegisterSecSurfaceInfoListener()
11617 {
11618 auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
11619 this->UpdateSecSurfaceInfo(secExtensionData, userid);
11620 };
11621 TLOGI(WmsLogTag::WMS_EVENT, "in");
11622 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
11623 TLOGE(WmsLogTag::WMS_EVENT, "failed");
11624 }
11625 }
11626
UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,uint64_t userId)11627 void SceneSessionManager::UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,
11628 uint64_t userId)
11629 {
11630 if (currentUserId_ != static_cast<int32_t>(userId)) {
11631 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
11632 currentUserId_.load(), userId);
11633 return;
11634 }
11635 if (constrainedModalUIExtData == nullptr) {
11636 TLOGE(WmsLogTag::WMS_UIEXT, "invalid constrainedModalUIExtData");
11637 return;
11638 }
11639 auto constrainedModalUIExtInfoMap = constrainedModalUIExtData->GetSecData();
11640 auto task = [constrainedModalUIExtInfoMap]()-> WSError {
11641 SceneInputManager::GetInstance().UpdateConstrainedModalUIExtInfo(constrainedModalUIExtInfoMap);
11642 return WSError::WS_OK;
11643 };
11644 taskScheduler_->PostAsyncTask(task, "UpdateConstrainedModalUIExtInfo");
11645 }
11646
RegisterConstrainedModalUIExtInfoListener()11647 void SceneSessionManager::RegisterConstrainedModalUIExtInfoListener()
11648 {
11649 auto callBack = [this](std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData, uint64_t userid) {
11650 this->UpdateConstrainedModalUIExtInfo(constrainedModalUIExtData, userid);
11651 };
11652 TLOGI(WmsLogTag::WMS_EVENT, "in");
11653 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack, true) != WM_OK) {
11654 TLOGE(WmsLogTag::WMS_EVENT, "failed");
11655 }
11656 }
11657
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)11658 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
11659 const AppForceLandscapeConfig& config)
11660 {
11661 if (bundleName.empty()) {
11662 TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
11663 return WSError::WS_ERROR_NULLPTR;
11664 }
11665 std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11666 appForceLandscapeMap_[bundleName] = config;
11667 TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
11668 bundleName.c_str(), config.mode_, config.homePage_.c_str());
11669 return WSError::WS_OK;
11670 }
11671
GetAppForceLandscapeConfig(const std::string & bundleName)11672 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
11673 {
11674 if (bundleName.empty()) {
11675 return {};
11676 }
11677 std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11678 if (appForceLandscapeMap_.empty() ||
11679 appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
11680 TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
11681 return {};
11682 }
11683 return appForceLandscapeMap_[bundleName];
11684 }
11685
TerminateSessionByPersistentId(int32_t persistentId)11686 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
11687 {
11688 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
11689 TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
11690 return WMError::WM_ERROR_INVALID_PERMISSION;
11691 }
11692 if (!SessionPermission::IsSystemAppCall()) {
11693 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
11694 return WMError::WM_ERROR_NOT_SYSTEM_APP;
11695 }
11696 auto sceneSession = GetSceneSession(persistentId);
11697 if (sceneSession == nullptr) {
11698 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
11699 return WMError::WM_ERROR_INVALID_PARAM;
11700 }
11701 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11702 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11703 return WMError::WM_ERROR_INVALID_PARAM;
11704 }
11705 sceneSession->Clear(true);
11706 TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
11707 return WMError::WM_OK;
11708 }
11709
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)11710 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
11711 {
11712 rootSceneProcessBackEventFunc_ = processBackEventFunc;
11713 TLOGI(WmsLogTag::WMS_EVENT, "called");
11714 }
11715
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)11716 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
11717 const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
11718 {
11719 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11720 TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
11721 return WMError::WM_ERROR_INVALID_PERMISSION;
11722 }
11723
11724 surfaceNodeIds.clear();
11725 TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
11726 for (auto persistentId : persistentIds) {
11727 TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
11728 auto sceneSession = GetSceneSession(persistentId);
11729 if (sceneSession == nullptr) {
11730 continue;
11731 }
11732 auto callingPid = sceneSession->GetCallingPid();
11733 auto surfaceNode = sceneSession->GetSurfaceNode();
11734 if (surfaceNode != nullptr && callingPid == pid) {
11735 surfaceNodeIds.push_back(surfaceNode->GetId());
11736 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
11737 if (leashWinSurfaceNode != nullptr) {
11738 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
11739 surfaceNodeIds.push_back(persistentId);
11740 }
11741 }
11742 }
11743
11744 return WMError::WM_OK;
11745 }
11746
ReleaseForegroundSessionScreenLock()11747 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
11748 {
11749 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11750 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11751 return WMError::WM_ERROR_INVALID_PERMISSION;
11752 }
11753 #ifdef POWER_MANAGER_ENABLE
11754 auto task = [this] {
11755 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11756 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11757 if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
11758 continue;
11759 }
11760 auto res = sceneSession->keepScreenLock_->UnLock();
11761 if (res != ERR_OK) {
11762 TLOGNE(WmsLogTag::DEFAULT,
11763 "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
11764 persistentId, sceneSession->GetWindowName().c_str(), res);
11765 return WMError::WM_ERROR_INVALID_OPERATION;
11766 }
11767 TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
11768 persistentId, sceneSession->GetWindowName().c_str());
11769 }
11770 return WMError::WM_OK;
11771 };
11772 return taskScheduler_->PostSyncTask(task, __func__);
11773 #else
11774 TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
11775 return WMError::WM_OK;
11776 #endif
11777 }
11778
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)11779 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
11780 {
11781 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
11782 auto task = [this, func] {
11783 closeTargetFloatWindowFunc_ = func;
11784 };
11785 taskScheduler_->PostTask(task, __func__);
11786 }
11787
CloseTargetFloatWindow(const std::string & bundleName)11788 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
11789 {
11790 if (!SessionPermission::IsSystemServiceCalling(false)) {
11791 TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
11792 return WMError::WM_ERROR_INVALID_PERMISSION;
11793 }
11794 auto task = [this, bundleName] {
11795 if (closeTargetFloatWindowFunc_) {
11796 TLOGNI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
11797 closeTargetFloatWindowFunc_(bundleName);
11798 }
11799 };
11800 taskScheduler_->PostTask(task, __func__);
11801 return WMError::WM_OK;
11802 }
11803
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)11804 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
11805 {
11806 SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
11807 }
11808
CloseTargetPiPWindow(const std::string & bundleName)11809 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
11810 {
11811 if (!SessionPermission::IsSystemServiceCalling(false)) {
11812 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11813 return WMError::WM_ERROR_INVALID_PERMISSION;
11814 }
11815 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11816 for (const auto& iter : sceneSessionMap_) {
11817 auto& session = iter.second;
11818 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
11819 session->GetSessionInfo().bundleName_ == bundleName) {
11820 session->NotifyCloseExistPipWindow();
11821 break;
11822 }
11823 }
11824 return WMError::WM_OK;
11825 }
11826
GetCurrentPiPWindowInfo(std::string & bundleName)11827 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
11828 {
11829 if (!SessionPermission::IsSystemServiceCalling(false)) {
11830 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11831 return WMError::WM_ERROR_INVALID_PERMISSION;
11832 }
11833 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11834 for (const auto& iter : sceneSessionMap_) {
11835 auto& session = iter.second;
11836 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
11837 bundleName = session->GetSessionInfo().bundleName_;
11838 return WMError::WM_OK;
11839 }
11840 }
11841 TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
11842 return WMError::WM_OK;
11843 }
11844
UpdateDarkColorModeToRS()11845 void SceneSessionManager::UpdateDarkColorModeToRS()
11846 {
11847 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
11848 if (appContext == nullptr) {
11849 TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
11850 return;
11851 }
11852 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
11853 if (config == nullptr) {
11854 TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
11855 return;
11856 }
11857 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
11858 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
11859 bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
11860 TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d",
11861 colorMode.c_str(), ret);
11862 }
11863
IsPcWindow(bool & isPcWindow)11864 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
11865 {
11866 isPcWindow = (systemConfig_.uiType_ == UI_TYPE_PC);
11867 return WMError::WM_OK;
11868 }
11869
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)11870 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
11871 {
11872 isPcOrPadFreeMultiWindowMode = (systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.freeMultiWindowEnable_);
11873 return WMError::WM_OK;
11874 }
11875
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)11876 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
11877 std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
11878 {
11879 if (!SessionPermission::IsSystemCalling()) {
11880 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11881 return WMError::WM_ERROR_INVALID_PERMISSION;
11882 }
11883
11884 auto task = [this, windowIds, &windowDisplayIdMap] {
11885 for (const uint64_t windowId : windowIds) {
11886 sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
11887 if (session == nullptr) {
11888 continue;
11889 }
11890 sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
11891 if (sessionProperty == nullptr) {
11892 continue;
11893 }
11894 DisplayId displayId = sessionProperty->GetDisplayId();
11895 TLOGNI(WmsLogTag::DEFAULT, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
11896 windowId, displayId);
11897 windowDisplayIdMap.insert({windowId, displayId});
11898 }
11899 return WMError::WM_OK;
11900 };
11901 return taskScheduler_->PostSyncTask(task, __func__);
11902 }
11903
IsLastFrameLayoutFinished(bool & isLayoutFinished)11904 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
11905 {
11906 if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
11907 TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
11908 return WSError::WS_ERROR_NULLPTR;
11909 }
11910 isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
11911 return WSError::WS_OK;
11912 }
11913
IsWindowRectAutoSave(const std::string & key,bool & enabled)11914 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled)
11915 {
11916 std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11917 if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11918 enabled = iter->second;
11919 } else {
11920 enabled = false;
11921 }
11922 return WMError::WM_OK;
11923 }
11924
SetIsWindowRectAutoSave(const std::string & key,bool enabled)11925 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled)
11926 {
11927 std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11928 if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11929 if (!enabled) {
11930 isWindowRectAutoSaveMap_.erase(key);
11931 } else {
11932 iter->second = enabled;
11933 }
11934 } else {
11935 if (enabled) {
11936 isWindowRectAutoSaveMap_.insert({key, enabled});
11937 }
11938 }
11939 }
11940
RemoveAppInfo(const std::string & bundleName)11941 void SceneSessionManager::RemoveAppInfo(const std::string& bundleName)
11942 {
11943 AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
11944 }
11945
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)11946 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
11947 {
11948 if (!SessionPermission::IsSystemServiceCalling()) {
11949 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11950 return WMError::WM_ERROR_INVALID_PERMISSION;
11951 }
11952 const char* const where = __func__;
11953 auto task = [this, persistentId, &hostWindowId, where]() {
11954 hostWindowId = INVALID_WINDOW_ID;
11955 sptr<Session> session = GetSceneSession(persistentId);
11956 while (session && SessionHelper::IsSubWindow(session->GetWindowType()))
11957 {
11958 session = session->GetParentSession();
11959 }
11960 if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
11961 hostWindowId = session->GetPersistentId();
11962 }
11963 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
11964 where, persistentId, hostWindowId);
11965 return WMError::WM_OK;
11966 };
11967 return taskScheduler_->PostSyncTask(task, where);
11968 }
11969
MinimizeMainSession(const std::string & bundleName,int32_t appIndex,int32_t userId)11970 WMError SceneSessionManager::MinimizeMainSession(const std::string& bundleName, int32_t appIndex, int32_t userId)
11971 {
11972 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
11973 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
11974 return WMError::WM_ERROR_INVALID_PERMISSION;
11975 }
11976 if ((currentUserId_ != userId && currentUserId_ != DEFAULT_USERID) ||
11977 (currentUserId_ == DEFAULT_USERID && userId != GetUserIdByUid(getuid()))) {
11978 TLOGW(WmsLogTag::WMS_LIFE, "currentUserId:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
11979 currentUserId_.load(), userId, GetUserIdByUid(getuid()));
11980 return WMError::WM_ERROR_INVALID_OPERATION;
11981 }
11982 const char* const where = __func__;
11983 taskScheduler_->PostAsyncTask([this, bundleName, appIndex, where] {
11984 std::vector<sptr<SceneSession>> mainSessions;
11985 GetMainSessionByBundleNameAndAppIndex(bundleName, appIndex, mainSessions);
11986 if (mainSessions.empty()) {
11987 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, not found any main session", where);
11988 return;
11989 }
11990 for (const auto& session : mainSessions) {
11991 session->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
11992 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d.", where, session->GetPersistentId());
11993 }
11994 }, __func__);
11995 return WMError::WM_OK;
11996 }
11997
ShiftAppWindowPointerEvent(int32_t sourcePersistentId,int32_t targetPersistentId)11998 WMError SceneSessionManager::ShiftAppWindowPointerEvent(int32_t sourcePersistentId, int32_t targetPersistentId)
11999 {
12000 TLOGD(WmsLogTag::WMS_PC, "sourcePersistentId %{public}d targetPersistentId %{public}d",
12001 sourcePersistentId, targetPersistentId);
12002 if (!(systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.freeMultiWindowEnable_)) {
12003 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
12004 }
12005 if (sourcePersistentId == targetPersistentId) {
12006 return WMError::WM_ERROR_INVALID_CALLING;
12007 }
12008 sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
12009 if (sourceSession == nullptr) {
12010 TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is nullptr", sourcePersistentId);
12011 return WMError::WM_ERROR_INVALID_SESSION;
12012 }
12013 if (!WindowHelper::IsAppWindow(sourceSession->GetWindowType())) {
12014 TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is not app window", sourcePersistentId);
12015 return WMError::WM_ERROR_INVALID_CALLING;
12016 }
12017 sptr<SceneSession> targetSession = GetSceneSession(targetPersistentId);
12018 if (targetSession == nullptr) {
12019 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is nullptr", targetPersistentId);
12020 return WMError::WM_ERROR_INVALID_SESSION;
12021 }
12022 if (!WindowHelper::IsAppWindow(targetSession->GetWindowType())) {
12023 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not app window", targetPersistentId);
12024 return WMError::WM_ERROR_INVALID_CALLING;
12025 }
12026 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
12027 TLOGE(WmsLogTag::WMS_PC, "verify bundle failed, source name is %{public}s but target name is %{public}s)",
12028 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
12029 return WMError::WM_ERROR_INVALID_CALLING;
12030 }
12031 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
12032 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not same bundle as calling", targetPersistentId);
12033 return WMError::WM_ERROR_INVALID_CALLING;
12034 }
12035 int32_t callingPid = IPCSkeleton::GetCallingPid();
12036 if (callingPid != targetSession->GetCallingPid()) {
12037 TLOGE(WmsLogTag::WMS_PC, "permission denied, not call by the same process");
12038 return WMError::WM_ERROR_INVALID_CALLING;
12039 }
12040 return ShiftAppWindowPointerEventInner(sourcePersistentId, targetPersistentId,
12041 targetSession->GetSessionProperty()->GetDisplayId());
12042 }
12043
ShiftAppWindowPointerEventInner(int32_t sourceWindowId,int32_t targetWindowId,DisplayId targetDisplayId)12044 WMError SceneSessionManager::ShiftAppWindowPointerEventInner(
12045 int32_t sourceWindowId, int32_t targetWindowId, DisplayId targetDisplayId)
12046 {
12047 return taskScheduler_->PostSyncTask([sourceWindowId, targetWindowId, targetDisplayId] {
12048 auto display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
12049 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
12050 if (display) {
12051 vpr = display->GetVirtualPixelRatio();
12052 }
12053 int32_t outside = static_cast<int32_t>(HOTZONE_TOUCH * vpr * 2); // double touch hotzone
12054 MMI::ShiftWindowParam param;
12055 param.sourceWindowId = sourceWindowId;
12056 param.targetWindowId = targetWindowId;
12057 param.x = -outside;
12058 param.y = -outside;
12059 int ret = MMI::InputManager::GetInstance()->ShiftAppPointerEvent(param, true);
12060 TLOGNI(WmsLogTag::WMS_PC, "sourceWindowId %{public}d targetWindowId %{public}d vpr %{public}f ret %{public}d",
12061 param.sourceWindowId, param.targetWindowId, vpr, ret);
12062 return ret == 0 ? WMError::WM_OK : WMError::WM_ERROR_INVALID_CALLING;
12063 }, __func__);
12064 }
12065
HasFloatingWindowForeground(const sptr<IRemoteObject> & abilityToken,bool & hasOrNot)12066 WMError SceneSessionManager::HasFloatingWindowForeground(const sptr<IRemoteObject>& abilityToken, bool& hasOrNot)
12067 {
12068 if (!abilityToken) {
12069 TLOGE(WmsLogTag::WMS_SYSTEM, "AbilityToken is null");
12070 return WMError::WM_ERROR_NULLPTR;
12071 }
12072 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12073 TLOGE(WmsLogTag::WMS_SYSTEM, "Permission denied, only for SA");
12074 return WMError::WM_ERROR_INVALID_PERMISSION;
12075 }
12076
12077 return taskScheduler_->PostSyncTask([this, &abilityToken, &hasOrNot, where = __func__] {
12078 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12079 for (const auto& [_, session] : sceneSessionMap_) {
12080 if (session && session->GetAbilityToken() == abilityToken &&
12081 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && session->IsSessionForeground()) {
12082 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s found", where);
12083 hasOrNot = true;
12084 return WMError::WM_OK;
12085 }
12086 }
12087 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s not found", where);
12088 hasOrNot = false;
12089 return WMError::WM_OK;
12090 }, __func__);
12091 }
12092
LockSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,bool isLock)12093 WMError SceneSessionManager::LockSessionByAbilityInfo(const AbilityInfoBase& abilityInfo, bool isLock)
12094 {
12095 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
12096 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
12097 return WMError::WM_ERROR_INVALID_PERMISSION;
12098 }
12099 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12100 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12101 return WMError::WM_ERROR_INVALID_PERMISSION;
12102 }
12103 TLOGI(WmsLogTag::WMS_LIFE,
12104 "bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s appIndex:%{public}d isLock:%{public}d",
12105 abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.abilityName.c_str(),
12106 abilityInfo.appIndex, isLock);
12107 if (!abilityInfo.IsValid()) {
12108 TLOGE(WmsLogTag::WMS_LIFE, "abilityInfo not valid");
12109 return WMError::WM_ERROR_INVALID_PARAM;
12110 }
12111 taskScheduler_->PostAsyncTask([this, abilityInfo, isLock, where = __func__] {
12112 std::vector<sptr<SceneSession>> mainSessions;
12113 GetMainSessionByAbilityInfo(abilityInfo, mainSessions);
12114 if (!mainSessions.empty()) {
12115 for (const auto& mainSession : mainSessions) {
12116 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, set isLocked %{public}d, persistentId:%{public}d",
12117 where, isLock, mainSession->GetPersistentId());
12118 mainSession->NotifySessionLockStateChange(isLock);
12119 }
12120 if (isLock) {
12121 return;
12122 }
12123 }
12124 if (isLock) {
12125 if (sessionLockedStateCacheSet_.size() > MAX_LOCK_STATUS_CACHE_SIZE) {
12126 auto iter = sessionLockedStateCacheSet_.begin();
12127 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, reach max erase begin:%{public}s", where, (*iter).c_str());
12128 sessionLockedStateCacheSet_.erase(iter);
12129 }
12130 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, update isLockedState into cache set", where);
12131 sessionLockedStateCacheSet_.insert(abilityInfo.ToKeyString());
12132 } else {
12133 sessionLockedStateCacheSet_.erase(abilityInfo.ToKeyString());
12134 }
12135 }, __func__);
12136 return WMError::WM_OK;
12137 }
12138 } // namespace OHOS::Rosen