• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <common/rs_common_def.h>
25 #include <hisysevent.h>
26 #include <parameters.h>
27 #include <hitrace_meter.h>
28 #include "parameter.h"
29 #include "session/host/include/pc_fold_screen_manager.h"
30 #include "publish/scb_dump_subscriber.h"
31 #include <ui/rs_node.h>
32 
33 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
34 #include <display_power_mgr_client.h>
35 #endif
36 
37 #ifdef POWER_MANAGER_ENABLE
38 #include <power_mgr_client.h>
39 #endif
40 
41 #ifdef RES_SCHED_ENABLE
42 #include "res_type.h"
43 #include "res_sched_client.h"
44 #endif
45 #include "scene_system_ability_listener.h"
46 
47 #include "color_parser.h"
48 #include "common/include/session_permission.h"
49 #include "display_manager.h"
50 #include "scene_input_manager.h"
51 #include "session/host/include/main_session.h"
52 #include "session/host/include/scb_system_session.h"
53 #include "session/host/include/scene_persistent_storage.h"
54 #include "session/host/include/session_utils.h"
55 #include "session/host/include/sub_session.h"
56 #include "session_helper.h"
57 #include "window_helper.h"
58 #include "screen_session_manager_client/include/screen_session_manager_client.h"
59 #include "singleton_container.h"
60 #include "xcollie/watchdog.h"
61 #include "session_manager_agent_controller.h"
62 #include "distributed_client.h"
63 #include "softbus_bus_center.h"
64 #include "perform_reporter.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 #include "session/host/include/multi_instance_manager.h"
70 #include "common/include/fold_screen_state_internel.h"
71 
72 #include "hidump_controller.h"
73 
74 #ifdef MEMMGR_WINDOW_ENABLE
75 #include "mem_mgr_client.h"
76 #include "mem_mgr_window_info.h"
77 #endif
78 
79 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
80 #include "sec_comp_enhance_kit.h"
81 #endif
82 
83 #ifdef IMF_ENABLE
84 #include <input_method_controller.h>
85 #endif // IMF_ENABLE
86 
87 namespace OHOS::Rosen {
88 namespace {
89 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
90 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
91 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
92 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
93 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
94 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
95 constexpr uint32_t MAX_BRIGHTNESS = 255;
96 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
97 constexpr int32_t SCALE_DIMENSION = 2;
98 constexpr int32_t TRANSLATE_DIMENSION = 2;
99 constexpr int32_t ROTAION_DIMENSION = 4;
100 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
101 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
102 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
103 const std::string EMPTY_DEVICE_ID = "";
104 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
105 
106 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
107 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
108 constexpr int VALUE_MAX_WIDTH = 5;
109 constexpr int MAX_RESEND_TIMES = 6;
110 constexpr int ORIEN_MAX_WIDTH = 12;
111 constexpr int OFFSET_MAX_WIDTH = 8;
112 constexpr int SCALE_MAX_WIDTH = 8;
113 constexpr int PID_MAX_WIDTH = 8;
114 constexpr int PARENT_ID_MAX_WIDTH = 6;
115 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
116 constexpr int32_t CANCEL_POINTER_ID = 99999999;
117 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
118 const std::string ARG_DUMP_ALL = "-a";
119 const std::string ARG_DUMP_WINDOW = "-w";
120 const std::string ARG_DUMP_SCREEN = "-s";
121 const std::string ARG_DUMP_DISPLAY = "-d";
122 const std::string ARG_DUMP_PIPLINE = "-p";
123 const std::string ARG_DUMP_SCB = "-b";
124 const std::string ARG_DUMP_DETAIL = "-c";
125 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
126 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
127 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
128 constexpr char SMALL_FOLD_PRODUCT_TYPE = '2';
129 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 10;
130 constexpr uint64_t VIRTUAL_DISPLAY_ID = 999;
131 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
132 constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000;
133 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 50;
134 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8;
135 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3;
136 constexpr uint32_t LIFECYCLE_ISOLATE_VERSION = 18;
137 constexpr uint64_t NOTIFY_START_ABILITY_TIMEOUT = 4000;
138 constexpr uint64_t START_UI_ABILITY_TIMEOUT = 3000;
139 
140 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
141     {"unspecified",                         OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
142     {"landscape",                           OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
143     {"portrait",                            OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
144     {"follow_recent",                       OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
145     {"landscape_inverted",                  OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
146     {"portrait_inverted",                   OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
147     {"auto_rotation",                       OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
148     {"auto_rotation_landscape",             OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
149     {"auto_rotation_portrait",              OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
150     {"auto_rotation_restricted",            OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
151     {"auto_rotation_landscape_restricted",  OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
152     {"auto_rotation_portrait_restricted",   OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
153     {"locked",                              OHOS::AppExecFwk::DisplayOrientation::LOCKED},
154     {"auto_rotation_unspecified",           OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
155     {"follow_desktop",                      OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
156 };
157 
158 const std::unordered_set<std::string> LAYOUT_INFO_WHITELIST = {
159     "SCBSmartDock",
160     "SCBExtScreenDock",
161     "status_bar_tray",
162     "status_bar_personal",
163     "status_bar_sound_panel",
164     "status_bar_notification_panel",
165     "status_bar_input_panel",
166     "status_bar_control_center",
167     "status_bar_wifi_panel",
168     "status_bar_input_method",
169     "status_bar_assistant_translate",
170     "status_bar_quick_note",
171     "status_bar_bluetooth_panel",
172     "status_bar_battery_panel",
173     "status_bar_focus_mode_paddle",
174     "SCBStatusBar"
175 };
176 
177 const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
178 
GetCurrentTime()179 std::string GetCurrentTime()
180 {
181     struct timespec tn;
182     clock_gettime(CLOCK_REALTIME, &tn);
183     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
184         static_cast<uint64_t>(tn.tv_nsec);
185     return std::to_string(uTime);
186 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)187 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
188 {
189     return a.first < b.first;
190 }
191 
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)192 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
193 {
194     if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
195         value = (*item.intsValue_)[0];
196         return true;
197     }
198     return false;
199 }
200 
GetPid()201 int32_t GetPid()
202 {
203     static int32_t pid = static_cast<int32_t>(getpid());
204     return pid;
205 }
206 
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)207 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
208 {
209     auto& metadata = abilityInfo->metadata;
210     for (const auto& item : metadata) {
211         if (item.name == "enable.remove.starting.window") {
212             TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window=%{public}s", item.value.c_str());
213             return item.value == "true";
214         }
215     }
216     TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window default false");
217     return false;
218 }
219 
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)220 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
221     AppExecFwk::ExtensionAbilityType extensionAbilityType)
222 {
223     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
224           element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
225     static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
226         AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
227     };
228     static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
229         std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
230         std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
231         std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
232         std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
233         std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
234         std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
235         std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
236         std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
237         std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
238         std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
239         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
240         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
241         std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
242         std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
243         std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
244         std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
245         std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
246         std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
247         std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
248         std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
249         std::make_tuple("com.huawei.hmos.settings", "WifiWindowSettingsAbility", "pc_settings"),
250     };
251 
252     if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
253         TLOGI(WmsLogTag::WMS_UIEXT, "ability in white list");
254         return true;
255     }
256 
257     auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
258         auto& [bundleName, abilityName, _] = item;
259         return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
260     });
261     if (it != elementNameWhitelist.end()) {
262         return true;
263     }
264 
265     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
266     return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
267         PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
268 }
269 
270 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
271 public:
272     BundleStatusCallback() = default;
273     virtual ~BundleStatusCallback() = default;
274 
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)275     void OnBundleStateChanged(const uint8_t installType,
276         const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
277 
OnBundleAdded(const std::string & bundleName,const int userId)278     void OnBundleAdded(const std::string& bundleName, const int userId) override
279     {
280         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
281     }
282 
OnBundleUpdated(const std::string & bundleName,const int userId)283     void OnBundleUpdated(const std::string& bundleName, const int userId) override
284     {
285         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
286     }
287 
OnBundleRemoved(const std::string & bundleName,const int userId)288     void OnBundleRemoved(const std::string& bundleName, const int userId) override
289     {
290         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
291     }
292 };
293 
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)294 bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
295 {
296     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
297         !avoidArea.rightRect_.IsUninitializedRect()) {
298         return false;
299     }
300     if (avoidArea.bottomRect_.IsUninitializedRect()) {
301         return true;
302     }
303     auto diff =
304         std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
305     return isVisible && diff <= 1;
306 }
307 } // namespace
308 
CreateInstance()309 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
310 {
311     sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
312     sessionManager->Init();
313     return sessionManager;
314 }
315 
GetInstance()316 SceneSessionManager& SceneSessionManager::GetInstance()
317 {
318     static sptr<SceneSessionManager> instance = CreateInstance();
319     return *instance;
320 }
321 
SceneSessionManager()322 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
323 {
324     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
325     if (!mainHandler_) {
326         auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
327         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
328     }
329     currentUserId_ = DEFAULT_USERID;
330     launcherService_ = sptr<AppExecFwk::LauncherService>::MakeSptr();
331     if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
332         TLOGE(WmsLogTag::DEFAULT, "Failed to register bundle status callback.");
333     }
334 
335     collaboratorDeathRecipient_ = sptr<AgentDeathRecipient>::MakeSptr(
336         [this](const sptr<IRemoteObject>& remoteObject) { this->ClearAllCollaboratorSessions(); });
337 
338     scbDumpSubscriber_ = ScbDumpSubscriber::Subscribe();
339 
340     listenerController_ = std::make_shared<SessionListenerController>(taskScheduler_);
341     windowFocusController_ = sptr<WindowFocusController>::MakeSptr();
342     ffrtQueueHelper_ = std::make_shared<FfrtQueueHelper>();
343 }
344 
~SceneSessionManager()345 SceneSessionManager::~SceneSessionManager()
346 {
347     ScbDumpSubscriber::UnSubscribe(scbDumpSubscriber_);
348 }
349 
Init()350 void SceneSessionManager::Init()
351 {
352     bool isScbCoreEnabled = system::GetParameter("persist.window.scbcore.enable", "1") == "1";
353     Session::SetScbCoreEnabled(isScbCoreEnabled);
354     bool isBackgroundWindowNotifyEnabled = system::GetParameter("persist.window.background.notify.enable", "0") == "1";
355     Session::SetBackgroundUpdateRectNotifyEnabled(isBackgroundWindowNotifyEnabled);
356 
357     constexpr uint64_t interval = 5 * 1000; // 5 second
358     if (HiviewDFX::Watchdog::GetInstance().AddThread(
359         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
360         TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
361     }
362 
363     bundleMgr_ = GetBundleManager();
364 
365     // Parse configuration.
366     LoadWindowSceneXml();
367     LoadWindowParameter();
368     InitPrepareTerminateConfig();
369 
370     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(sptr<DisplayChangeListener>::MakeSptr());
371     ScreenSessionManagerClient::GetInstance().RegisterScreenConnectionChangeListener(
372         sptr<ScreenConnectionChangeListener>::MakeSptr());
373 
374     // create handler for inner command at server
375     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
376     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
377     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
378     if (ret != 0) {
379         TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
380     }
381     taskScheduler_->SetExportHandler(eventHandler_);
382 
383     scbSessionHandler_ = sptr<ScbSessionHandler>::MakeSptr();
384     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
385     StartWindowInfoReportLoop();
386     TLOGI(WmsLogTag::DEFAULT, "SSM init success.");
387 
388     RegisterAppListener();
389     openDebugTrace_ = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
390     isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1")  == "1";
391 
392     // Input init.
393     SceneInputManager::GetInstance().Init();
394     RegisterFlushWindowInfoCallback();
395 
396     // MMI window state error check
397     int32_t retCode = MMI::InputManager::GetInstance()->
398         RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
399         this->NotifyWindowStateErrorFromMMI(pid, persistentId);
400     });
401     TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
402 
403     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
404         MultiInstanceManager::GetInstance().Init(bundleMgr_, taskScheduler_);
405         MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
406     }
407     AbilityInfoManager::GetInstance().Init(bundleMgr_);
408     AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
409 
410     InitVsyncStation();
411     UpdateDarkColorModeToRS();
412     CreateRootSceneSession();
413     std::shared_ptr<FoldScreenStatusChangeCallback> callback = std::make_shared<FoldScreenStatusChangeCallback>(
414         std::bind(&SceneSessionManager::UpdateSessionCrossAxisState, this, std::placeholders::_1,
415         std::placeholders::_2, std::placeholders::_3));
416     PcFoldScreenManager::GetInstance().RegisterFoldScreenStatusChangeCallback(0, callback);
417 
418     InitSnapshotCache();
419 }
420 
RegisterFlushWindowInfoCallback()421 void SceneSessionManager::RegisterFlushWindowInfoCallback()
422 {
423     SceneInputManager::GetInstance().
424         RegisterFlushWindowInfoCallback([this]() { FlushWindowInfoToMMI(); });
425 }
426 
InitVsyncStation()427 void SceneSessionManager::InitVsyncStation()
428 {
429     NodeId nodeId = 0;
430     vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
431 }
432 
InitScheduleUtils()433 void SceneSessionManager::InitScheduleUtils()
434 {
435 #ifdef RES_SCHED_ENABLE
436     SCBThreadInfo threadInfo = {
437         .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
438         .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
439     };
440     std::unordered_map<std::string, std::string> payload {
441         { "pid", threadInfo.scbPid_ },
442         { "tid", threadInfo.scbTid_ },
443         { "uid", threadInfo.scbUid_ },
444         { "bundleName", threadInfo.scbBundleName_ },
445     };
446     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
447     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
448     auto task = [threadInfo = std::move(threadInfo)]() mutable {
449         threadInfo.ssmThreadName_ = "OS_SceneSession";
450         threadInfo.ssmTid_ = std::to_string(gettid());
451         const int32_t userInteraction = 2;
452         std::unordered_map<std::string, std::string> payload{
453             { "pid", threadInfo.scbPid_ },
454             { "tid", threadInfo.ssmTid_ },
455             { "uid", threadInfo.scbUid_ },
456             { "extType", "10002" },
457             { "cgroupPrio", "1" },
458             { "isSa", "0" },
459             { "threadName", threadInfo.ssmThreadName_ }
460         };
461         uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
462         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
463         TLOGNI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
464         sptr<ISystemAbilityManager> systemAbilityManager =
465             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
466         if (!systemAbilityManager) {
467             TLOGNE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
468             return;
469         }
470         auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
471         int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
472         if (ret != ERR_OK) {
473             TLOGNI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
474         }
475     };
476     taskScheduler_->PostAsyncTask(task, "changeQosTask");
477 #endif
478 }
479 
UpdateSessionCrossAxisState(DisplayId displayId,SuperFoldStatus status,SuperFoldStatus prevStatus)480 void SceneSessionManager::UpdateSessionCrossAxisState(DisplayId displayId, SuperFoldStatus status,
481     SuperFoldStatus prevStatus)
482 {
483     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
484     for (const auto& [_, sceneSession] : sceneSessionMap_) {
485         if (sceneSession == nullptr) {
486             TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
487             continue;
488         }
489         sceneSession->UpdateCrossAxis();
490     }
491 }
492 
RegisterAppListener()493 void SceneSessionManager::RegisterAppListener()
494 {
495     appAnrListener_ = sptr<AppAnrListener>::MakeSptr();
496     auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
497     if (appMgrClient == nullptr) {
498         TLOGE(WmsLogTag::DEFAULT, "appMgrClient is nullptr.");
499     } else {
500         auto ret = static_cast<int32_t>(appMgrClient->RegisterAppDebugListener(appAnrListener_));
501         TLOGI(WmsLogTag::DEFAULT, "Register app debug listener, %{public}d.", ret);
502     }
503 }
504 
LoadWindowParameter()505 void SceneSessionManager::LoadWindowParameter()
506 {
507     const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "HandsetSmartWindow");
508     if (multiWindowUIType == "HandsetSmartWindow") {
509         systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW;
510     } else if (multiWindowUIType == "FreeFormMultiWindow") {
511         systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW;
512     } else if (multiWindowUIType == "TabletSmartWindow") {
513         systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW;
514     } else {
515         TLOGE(WmsLogTag::DEFAULT, "unknown multiWindowUIType:%{public}s.", multiWindowUIType.c_str());
516     }
517     appWindowSceneConfig_.multiWindowUIType_ = multiWindowUIType;
518 }
519 
LoadWindowSceneXml()520 void SceneSessionManager::LoadWindowSceneXml()
521 {
522     if (WindowSceneConfig::LoadConfigXml()) {
523         if (WindowSceneConfig::GetConfig().IsMap()) {
524             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
525         }
526         ConfigWindowSceneXml();
527     } else {
528         TLOGE(WmsLogTag::DEFAULT, "Load window scene xml failed");
529     }
530     ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
531         appWindowSceneConfig_.keyboardAnimationOut_);
532 }
533 
InitPrepareTerminateConfig()534 void SceneSessionManager::InitPrepareTerminateConfig()
535 {
536     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
537     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
538         PREPARE_TERMINATE_ENABLE_SIZE);
539     TLOGI(WmsLogTag::DEFAULT, "%{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
540     if (retSysParam > 0 && !std::strcmp(value, "true")) {
541         isPrepareTerminateEnable_ = true;
542     }
543 }
544 
ConfigWindowSceneXml()545 void SceneSessionManager::ConfigWindowSceneXml()
546 {
547     const auto& config = WindowSceneConfig::GetConfig();
548     WindowSceneConfig::ConfigItem item = config["windowEffect"];
549     if (item.IsMap()) {
550         ConfigWindowEffect(item);
551     }
552 
553     item = config["decor"];
554     if (item.IsMap()) {
555         ConfigDecor(item);
556     }
557 
558     item = config["backgroundswitch"];
559     int32_t param = -1;
560     systemConfig_.backgroundswitch = GetSingleIntItem(item, param) && param == 1;
561     TLOGD(WmsLogTag::DEFAULT, "Load backgroundswitch %{public}d", systemConfig_.backgroundswitch);
562     item = config["defaultWindowMode"];
563     if (GetSingleIntItem(item, param) &&
564         (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
565         param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
566         systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
567     }
568     item = config["defaultMaximizeMode"];
569     if (GetSingleIntItem(item, param) &&
570         (param == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
571          param == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
572         SceneSession::maximizeMode_ = static_cast<MaximizeMode>(param);
573     }
574     item = config["keyboardAnimation"];
575     if (item.IsMap()) {
576         ConfigKeyboardAnimation(item);
577     }
578     item = config["maxFloatingWindowSize"];
579     if (GetSingleIntItem(item, param)) {
580         systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(param);
581     }
582     item = config["windowAnimation"];
583     if (item.IsMap()) {
584         ConfigWindowAnimation(item);
585     }
586     item = config["startWindowTransitionAnimation"];
587     if (item.IsMap()) {
588         ConfigStartingWindowAnimation(item);
589     }
590     ConfigFreeMultiWindow();
591     ConfigWindowSizeLimits();
592     ConfigSnapshotScale();
593     ConfigWindowSceneXml(config);
594 }
595 
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)596 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
597 {
598     WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
599     if (item.IsMap()) {
600         ConfigSystemUIStatusBar(item);
601     }
602     item = config["backgroundScreenLock"].GetProp("enable");
603     if (item.IsBool()) {
604         appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
605     }
606     item = config["rotationMode"];
607     if (item.IsString()) {
608         appWindowSceneConfig_.rotationMode_ = item.stringValue_;
609     }
610     item = config["immersive"];
611     if (item.IsMap()) {
612         ConfigWindowImmersive(item);
613     }
614     item = config["supportTypeFloatWindow"].GetProp("enable");
615     if (item.IsBool()) {
616         systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
617     }
618     item = config["singleHandCompatibleMode"];
619     if (item.IsMap()) {
620         ConfigSingleHandCompatibleMode(item);
621     }
622 }
623 
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)624 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
625 {
626     AppWindowSceneConfig config;
627     WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
628     if (item.IsMap()) {
629         if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
630             appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
631                 config.windowImmersive_.desktopStatusBarConfig_;
632         }
633     }
634     item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
635     if (item.IsMap()) {
636         if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
637             appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
638                 config.windowImmersive_.upDownStatusBarConfig_;
639         }
640     }
641     item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
642     if (item.IsMap()) {
643         if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
644             appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
645                 config.windowImmersive_.leftRightStatusBarConfig_;
646         }
647     }
648 }
649 
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)650 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
651     StatusBarConfig& statusBarConfig)
652 {
653     WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
654     if (item.IsBool()) {
655         statusBarConfig.showHide_ = item.boolValue_;
656     }
657     item = config["contentColor"];
658     if (item.IsString()) {
659         statusBarConfig.contentColor_ = item.stringValue_;
660     }
661     item = config["backgroundColor"];
662     if (item.IsString()) {
663         statusBarConfig.backgroundColor_ = item.stringValue_;
664     }
665     return true;
666 }
667 
ConfigFreeMultiWindow()668 void SceneSessionManager::ConfigFreeMultiWindow()
669 {
670     const auto& config = WindowSceneConfig::GetConfig();
671     WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
672     if (freeMultiWindowConfig.IsMap()) {
673         auto supportItem = freeMultiWindowConfig.GetProp("enable");
674         if (supportItem.IsBool()) {
675             systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
676         }
677         auto item = freeMultiWindowConfig["decor"];
678         if (item.IsMap()) {
679             ConfigDecor(item, false);
680         }
681         int32_t param = -1;
682         item = freeMultiWindowConfig["defaultWindowMode"];
683         if (GetSingleIntItem(item, param) &&
684             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
685              param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
686             systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
687                 static_cast<WindowMode>(static_cast<uint32_t>(param));
688         }
689         item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
690         if (GetSingleIntItem(item, param) && (param > 0)) {
691             systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
692         }
693     }
694 }
695 
LoadFreeMultiWindowConfig(bool enable)696 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
697 {
698     FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
699     if (enable) {
700         systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
701         systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
702         systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
703     } else {
704         const auto& config = WindowSceneConfig::GetConfig();
705         auto item = config["decor"];
706         if (item.IsMap()) {
707             ConfigDecor(item, true);
708         }
709         int32_t param = -1;
710         item = config["defaultWindowMode"];
711         if (GetSingleIntItem(item, param) &&
712             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
713              param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
714             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
715         }
716     }
717     systemConfig_.freeMultiWindowEnable_ = enable;
718     rsInterface_.SetFreeMultiWindowStatus(enable);
719 }
720 
GetSystemSessionConfig() const721 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
722 {
723     return systemConfig_;
724 }
725 
SwitchFreeMultiWindow(bool enable)726 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
727 {
728     if (!systemConfig_.freeMultiWindowSupport_) {
729         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "device not support");
730         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
731     }
732     LoadFreeMultiWindowConfig(enable);
733     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
734     for (const auto& [_, sceneSession] : sceneSessionMap_) {
735         if (sceneSession == nullptr) {
736             continue;
737         }
738         sceneSession->SwitchFreeMultiWindow(enable);
739     }
740     WindowStyleType type = enable ?
741             WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
742     SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
743     return WSError::WS_OK;
744 }
745 
GetFreeMultiWindowEnableState(bool & enable)746 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
747 {
748     enable = systemConfig_.freeMultiWindowEnable_;
749     return WSError::WS_OK;
750 }
751 
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)752 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject>& token,
753     const ContinueState& continueState)
754 {
755     TLOGI(WmsLogTag::WMS_LIFE, "in");
756     int32_t callingUid = IPCSkeleton::GetCallingUid();
757     return taskScheduler_->PostSyncTask([this, token, continueState, callingUid, where = __func__] {
758         sptr <SceneSession> sceneSession = FindSessionByToken(token);
759         if (sceneSession == nullptr) {
760             TLOGNE(WmsLogTag::DEFAULT, "fail to find session by token.");
761             return WSError::WS_ERROR_INVALID_PARAM;
762         }
763         sceneSession->SetSessionInfoContinueState(continueState);
764         DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
765             static_cast<AAFwk::ContinueState>(continueState), callingUid);
766         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id:%{public}d, continueState:%{public}d",
767             where, sceneSession->GetPersistentId(), continueState);
768         return WSError::WS_OK;
769     }, __func__);
770 }
771 
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)772 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
773 {
774     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
775     if (item.IsBool()) {
776         if (mainConfig) {
777             systemConfig_.isSystemDecorEnable_ = item.boolValue_;
778         } else {
779             systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
780         }
781         bool decorEnable = item.boolValue_;
782         uint32_t support = 0;
783         std::vector<std::string> supportedModes;
784         item = decorConfig["supportedMode"];
785         if (item.IsStrings()) {
786             supportedModes = *item.stringsValue_;
787         }
788         for (auto mode : supportedModes) {
789             if (mode == "fullscreen") {
790                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
791             } else if (mode == "floating") {
792                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
793             } else if (mode == "pip") {
794                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
795             } else if (mode == "split") {
796                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
797                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
798             } else {
799                 TLOGW(WmsLogTag::DEFAULT, "Invalid supporedMode");
800                 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
801                 break;
802             }
803         }
804         if (mainConfig && item.IsStrings()) {
805             systemConfig_.decorWindowModeSupportType_ = support;
806         }
807         if (!mainConfig && item.IsStrings()) {
808             systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
809         }
810     }
811 }
812 
AddAlphaToColor(float alpha,std::string & color)813 static void AddAlphaToColor(float alpha, std::string& color)
814 {
815     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
816         return;
817     }
818 
819     uint32_t alphaValue = 0xFF * alpha;
820     std::ostringstream ss;
821     ss << std::hex << alphaValue;
822     std::string strAlpha = ss.str();
823     if (strAlpha.size() == 1) {
824         strAlpha.append(1, '0');
825     }
826 
827     color.insert(1, strAlpha);
828 }
829 
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)830 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
831 {
832     return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
833         (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) == AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
834 }
835 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)836 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
837 {
838     AppWindowSceneConfig config;
839     // config corner radius
840     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
841     if (item.IsMap()) {
842         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
843             appWindowSceneConfig_ = config;
844         }
845     }
846 
847     // config shadow
848     item = effectConfig["appWindows"]["shadow"]["focused"];
849     if (item.IsMap()) {
850         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
851             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
852         }
853     }
854     item = effectConfig["appWindows"]["shadow"]["unfocused"];
855     if (item.IsMap()) {
856         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
857             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
858         }
859     }
860     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
861     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
862 
863     // config shadow in dark mode
864     item = effectConfig["appWindows"]["shadowDark"]["focused"];
865     if (item.IsMap()) {
866         if (ConfigAppWindowShadow(item, config.focusedShadowDark_)) {
867             appWindowSceneConfig_.focusedShadowDark_ = config.focusedShadowDark_;
868         }
869     }
870     item = effectConfig["appWindows"]["shadowDark"]["unfocused"];
871     if (item.IsMap()) {
872         if (ConfigAppWindowShadow(item, config.unfocusedShadowDark_)) {
873             appWindowSceneConfig_.unfocusedShadowDark_ = config.unfocusedShadowDark_;
874         }
875     }
876     AddAlphaToColor(appWindowSceneConfig_.focusedShadowDark_.alpha_, appWindowSceneConfig_.focusedShadowDark_.color_);
877     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadowDark_.alpha_,
878         appWindowSceneConfig_.unfocusedShadowDark_.color_);
879 
880     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "successfully");
881 }
882 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)883 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
884 {
885     static const std::unordered_map<std::string, float> stringToCornerRadius = {
886         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
887         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
888     };
889 
890     if (item.IsString()) {
891         auto value = item.stringValue_;
892         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
893             out = stringToCornerRadius.at(value);
894             return true;
895         }
896     }
897     return false;
898 }
899 
SetEnableInputEvent(bool enabled)900 void SceneSessionManager::SetEnableInputEvent(bool enabled)
901 {
902     TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
903     enableInputEvent_ = enabled;
904 }
905 
IsInputEventEnabled() const906 bool SceneSessionManager::IsInputEventEnabled() const
907 {
908     return enableInputEvent_;
909 }
910 
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)911 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
912 {
913     for (const auto persistentId : alivePersistentIds_) {
914         if (std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId) !=
915             recoveredPersistentIds.end()) {
916             continue;
917         }
918         auto sceneSession = GetSceneSession(persistentId);
919         if (sceneSession == nullptr) {
920             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
921             continue;
922         }
923         if (sceneSession->IsRecovered()) {
924             TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
925             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
926             visibleWindowCountMap_.erase(sceneSession->GetCallingPid());
927             EraseSceneSessionAndMarkDirtyLocked(persistentId);
928             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
929                 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
930                 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
931             }
932         }
933     }
934 }
935 
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)936 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
937 {
938     TLOGI(WmsLogTag::WMS_RECOVER, "persistentIds recovered=%{public}zu. CurrentUserId=%{public}d",
939         recoveredPersistentIds.size(), currentUserId_.load());
940 
941     taskScheduler_->PostAsyncTask([this, recoveredPersistentIds]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
942         ClearUnrecoveredSessions(recoveredPersistentIds);
943         std::list<AAFwk::SessionInfo> abilitySessionInfos;
944         for (const auto persistentId : recoveredPersistentIds) {
945             if (failRecoveredPersistentIdSet_.count(persistentId)) {
946                 TLOGNI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId=%{public}d, continue", persistentId);
947                 continue;
948             }
949             auto sceneSession = GetSceneSession(persistentId);
950             if (sceneSession == nullptr) {
951                 TLOGNE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
952                 continue;
953             }
954             const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
955             TLOGND(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d", persistentId);
956             abilitySessionInfos.emplace_back(*abilitySessionInfo);
957         }
958         std::vector<int32_t> unrecoverableSessionIds;
959         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
960             abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
961         TLOGNI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds=%{public}zu",
962             unrecoverableSessionIds.size());
963         for (const auto sessionId : unrecoverableSessionIds) {
964             auto sceneSession = GetSceneSession(sessionId);
965             if (sceneSession == nullptr) {
966                 TLOGNW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId=%{public}d ",
967                     sessionId);
968                 continue;
969             }
970             const auto& sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
971             TLOGNI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId=%{public}d", sessionId);
972             ExceptionInfo exceptionInfo;
973             sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo);
974         }
975         RemoveFailRecoveredSession();
976     }, __func__);
977 }
978 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)979 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
980     WindowShadowConfig& outShadow)
981 {
982     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
983     if (item.IsString()) {
984         auto color = item.stringValue_;
985         uint32_t colorValue;
986         if (!ColorParser::Parse(color, colorValue)) {
987             return false;
988         }
989         outShadow.color_ = color;
990     }
991 
992     item = shadowConfig["offsetX"];
993     if (item.IsFloats()) {
994         auto offsetX = *item.floatsValue_;
995         if (offsetX.size() != 1) {
996             return false;
997         }
998         outShadow.offsetX_ = offsetX[0];
999     }
1000 
1001     item = shadowConfig["offsetY"];
1002     if (item.IsFloats()) {
1003         auto offsetY = *item.floatsValue_;
1004         if (offsetY.size() != 1) {
1005             return false;
1006         }
1007         outShadow.offsetY_ = offsetY[0];
1008     }
1009 
1010     item = shadowConfig["alpha"];
1011     if (item.IsFloats()) {
1012         auto alpha = *item.floatsValue_;
1013         if (alpha.size() != 1 ||
1014             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
1015             return false;
1016         }
1017         outShadow.alpha_ = alpha[0];
1018     }
1019 
1020     item = shadowConfig["radius"];
1021     if (item.IsFloats()) {
1022         auto radius = *item.floatsValue_;
1023         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
1024             return false;
1025         }
1026         outShadow.radius_ = radius[0];
1027     }
1028 
1029     return true;
1030 }
1031 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)1032 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
1033     KeyboardSceneAnimationConfig& config)
1034 {
1035     if (item.IsMap() && item.mapValue_->count("curve")) {
1036         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1037         config.curveType_ = curveType;
1038         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1039             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1040             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1041             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1042             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1043         }
1044     }
1045 
1046     const WindowSceneConfig::ConfigItem& duration = item["duration"];
1047     if (duration.IsInts()) {
1048         auto numbers = *duration.intsValue_;
1049         if (numbers.size() == 1) {
1050             config.duration_ = static_cast<uint32_t>(numbers[0]);
1051         }
1052     }
1053 }
1054 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)1055 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
1056 {
1057     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
1058     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
1059 
1060     // config system animation
1061     const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
1062     systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
1063         {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
1064         appConfigIn.duration_);
1065     const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
1066     systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
1067         {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
1068         appConfigOut.duration_);
1069 }
1070 
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)1071 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
1072     KeyboardSceneAnimationConfig& animationOut)
1073 {
1074     if (!systemConfig_.animationIn_.curveType_.empty() && !systemConfig_.animationOut_.curveType_.empty()) {
1075         TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
1076             "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
1077             systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
1078             systemConfig_.animationOut_.duration_);
1079         return;
1080     }
1081 
1082     // default animation curve params
1083     constexpr char CURVETYPE[] = "interpolatingSpring";
1084     constexpr float IN_CTRLX1 = 0.0f;
1085     constexpr float OUT_CTRLX1 = 4.0f;
1086     constexpr float CTRLY1 = 1.0f;
1087     constexpr float CTRLX2 = 342.0f;
1088     constexpr float CTRLY2 = 37.0f;
1089     constexpr uint32_t DURATION = 150;
1090 
1091     if (systemConfig_.animationIn_.curveType_.empty()) {
1092         std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1093         // update system config for client
1094         systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1095         // update app config for server
1096         animationIn.curveType_ = CURVETYPE;
1097         animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1098         animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1099         animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1100         animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1101         animationIn.duration_ = DURATION;
1102         TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationIn");
1103     }
1104 
1105     if (systemConfig_.animationOut_.curveType_.empty()) {
1106         std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1107         // update system config for client
1108         systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1109         // update app config for server
1110         animationOut.curveType_ = CURVETYPE;
1111         animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1112         animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1113         animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1114         animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1115         animationOut.duration_ = DURATION;
1116         TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationOut");
1117     }
1118 }
1119 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1120 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1121 {
1122     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1123     if (item.IsMap() && item.mapValue_->count("curve")) {
1124         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1125         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1126         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1127             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1128             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1129             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1130             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1131         }
1132     }
1133     item = windowAnimationConfig["timing"]["duration"];
1134     if (item.IsInts() && item.intsValue_->size() == 1) {
1135         auto duration = *item.intsValue_;
1136         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1137     }
1138     item = windowAnimationConfig["scale"];
1139     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1140         auto scales = *item.floatsValue_;
1141         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1142         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1143     }
1144     item = windowAnimationConfig["rotation"];
1145     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1146         auto rotations = *item.floatsValue_;
1147         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1148         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1149         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1150         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1151     }
1152     item = windowAnimationConfig["translate"];
1153     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1154         auto translates = *item.floatsValue_;
1155         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1156         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1157     }
1158     item = windowAnimationConfig["opacity"];
1159     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1160         auto opacity = *item.floatsValue_;
1161         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1162     }
1163 }
1164 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1165 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1166 {
1167     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1168     auto item = configItem.GetProp("enable");
1169     if (item.IsBool()) {
1170         config.enabled_ = item.boolValue_;
1171     }
1172     item = configItem["timing"];
1173     if (item.IsMap() && item.mapValue_->count("curve")) {
1174         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1175     }
1176     item = configItem["timing"]["duration"];
1177     if (item.IsInts() && item.intsValue_->size() == 1) {
1178         config.duration_ = (*item.intsValue_)[0];
1179     }
1180     item = configItem["opacityStart"];
1181     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1182         config.opacityStart_ = (*item.floatsValue_)[0];
1183     }
1184     item = configItem["opacityEnd"];
1185     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1186         config.opacityEnd_ = (*item.floatsValue_)[0];
1187     }
1188 }
1189 
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1190 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1191     const WindowSceneConfig::ConfigItem& curveConfig)
1192 {
1193     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1194         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1195     static std::unordered_set<std::string> paramCurveSet = {
1196         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1197 
1198     std::string curveName = "easeOut";
1199     const auto& nameItem = curveConfig.GetProp("name");
1200     if (!nameItem.IsString()) {
1201         return {curveName, {}};
1202     }
1203 
1204     std::string name = nameItem.stringValue_;
1205     std::vector<float> curveParams;
1206 
1207     if (paramCurveSet.find(name) != paramCurveSet.end()) {
1208         curveName = name;
1209         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1210         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1211             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1212                 curveParams.begin());
1213         }
1214     } else {
1215         auto iter = curveSet.find(name);
1216         if (iter != curveSet.end()) {
1217             curveName = name;
1218         }
1219     }
1220 
1221     return {curveName, curveParams};
1222 }
1223 
1224 
ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem & configItem)1225 void SceneSessionManager::ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem& configItem)
1226 {
1227     auto& config = singleHandCompatibleModeConfig_;
1228     auto item = configItem.GetProp("enable");
1229     if (item.IsBool()) {
1230         config.enabled = item.boolValue_;
1231     }
1232     item = configItem["singleHandScale"];
1233     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1234         config.singleHandScale = (*item.floatsValue_)[0];
1235     }
1236     item = configItem["heightChangeRatio"];
1237     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1238         config.heightChangeRatio = (*item.floatsValue_)[0];
1239     }
1240     item = configItem["widthChangeRatio"];
1241     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1242         config.widthChangeRatio = (*item.floatsValue_)[0];
1243     }
1244 }
1245 
1246 
ConfigWindowSizeLimits()1247 void SceneSessionManager::ConfigWindowSizeLimits()
1248 {
1249     const auto& config = WindowSceneConfig::GetConfig();
1250     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1251     if (item.IsMap()) {
1252         ConfigMainWindowSizeLimits(item);
1253     }
1254 
1255     item = config["subWindowSizeLimits"];
1256     if (item.IsMap()) {
1257         ConfigSubWindowSizeLimits(item);
1258     }
1259 
1260     item = config["dialogWindowSizeLimits"];
1261     if (item.IsMap()) {
1262         ConfigDialogWindowSizeLimits(item);
1263     }
1264 }
1265 
ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem & dialogWindowSizeConifg)1266 void SceneSessionManager::ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem& dialogWindowSizeConifg)
1267 {
1268     auto item = dialogWindowSizeConifg["miniWidth"];
1269     if (item.IsInts()) {
1270         auto numbers = *item.intsValue_;
1271         if (numbers.size() == 1) {
1272             systemConfig_.miniWidthOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1273         }
1274     }
1275 
1276     item = dialogWindowSizeConifg["miniHeight"];
1277     if (item.IsInts()) {
1278         auto numbers = *item.intsValue_;
1279         if (numbers.size() == 1) {
1280             systemConfig_.miniHeightOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1281         }
1282     }
1283 }
1284 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1285 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1286 {
1287     auto item = mainWindowSizeConifg["miniWidth"];
1288     if (item.IsInts()) {
1289         auto numbers = *item.intsValue_;
1290         if (numbers.size() == 1) {
1291             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1292         }
1293     }
1294 
1295     item = mainWindowSizeConifg["miniHeight"];
1296     if (item.IsInts()) {
1297         auto numbers = *item.intsValue_;
1298         if (numbers.size() == 1) {
1299             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1300         }
1301     }
1302 }
1303 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1304 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1305 {
1306     auto item = subWindowSizeConifg["miniWidth"];
1307     if (item.IsInts()) {
1308         auto numbers = *item.intsValue_;
1309         if (numbers.size() == 1) {
1310             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1311         }
1312     }
1313 
1314     item = subWindowSizeConifg["miniHeight"];
1315     if (item.IsInts()) {
1316         auto numbers = *item.intsValue_;
1317         if (numbers.size() == 1) {
1318             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1319         }
1320     }
1321 }
1322 
ConfigSnapshotScale()1323 void SceneSessionManager::ConfigSnapshotScale()
1324 {
1325     const auto& config = WindowSceneConfig::GetConfig();
1326     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1327     if (item.IsFloats()) {
1328         auto snapshotScale = *item.floatsValue_;
1329         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1330             return;
1331         }
1332         snapshotScale_ = snapshotScale[0];
1333     }
1334 }
1335 
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1336 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1337 {
1338     TLOGI(WmsLogTag::WMS_IMMS, "load");
1339     WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1340     if (item.IsInts() && item.intsValue_->size() == 1) {
1341         bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1342         appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1343         TLOGI(WmsLogTag::WMS_IMMS, "showInLandscapeMode %{public}d",
1344             appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1345     }
1346 
1347     item = statusBarConfig["immersiveStatusBarBgColor"];
1348     if (item.IsString()) {
1349         auto color = item.stringValue_;
1350         uint32_t colorValue;
1351         if (!ColorParser::Parse(color, colorValue)) {
1352             return;
1353         }
1354         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1355         TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarBgColor %{public}s",
1356             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1357     }
1358 
1359     item = statusBarConfig["immersiveStatusBarContentColor"];
1360     if (item.IsString()) {
1361         auto color = item.stringValue_;
1362         uint32_t colorValue;
1363         if (!ColorParser::Parse(color, colorValue)) {
1364             return;
1365         }
1366         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1367         TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarContentColor %{public}s",
1368             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1369     }
1370 }
1371 
ConfigSupportFollowParentWindowLayout()1372 void SceneSessionManager::ConfigSupportFollowParentWindowLayout()
1373 {
1374     TLOGI(WmsLogTag::WMS_SUB, "support");
1375     auto task = [this] {
1376         systemConfig_.supportFollowParentWindowLayout_ = true;
1377     };
1378     taskScheduler_->PostAsyncTask(task, "ConfigSupportFollowParentWindowLayout");
1379 }
1380 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1381 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1382 {
1383     rootSceneContextWeak_ = contextWeak;
1384 }
1385 
CreateRootSceneSession()1386 void SceneSessionManager::CreateRootSceneSession()
1387 {
1388     system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1389     auto specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1390     specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1391         return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1392     };
1393     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1394         return this->GetSceneSessionVectorByType(type);
1395     };
1396     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1397         return this->GetAINavigationBarArea(displayId);
1398     };
1399     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1400         this->UpdateAvoidArea(persistentId);
1401     };
1402     specificCb->onNotifyAvoidAreaChange_ = [this](const sptr<AvoidArea>& avoidArea, AvoidAreaType type) {
1403         onNotifyAvoidAreaChangeForRootFunc_(avoidArea, type);
1404     };
1405     rootSceneSession_ = sptr<RootSceneSession>::MakeSptr(specificCb);
1406     rootSceneSession_->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1407     rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1408     AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1409     rootSceneSession_->RegisterGetStatusBarAvoidHeightFunc([this](WSRect& barArea) {
1410         return this->GetStatusBarAvoidHeight(barArea);
1411     });
1412     rootSceneSession_->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
1413         return this->GetStatusBarConstantlyShow(displayId, isVisible);
1414     });
1415 }
1416 
GetRootSceneSession()1417 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1418 {
1419     return rootSceneSession_;
1420 }
1421 
UpdateRootSceneAvoidArea()1422 void SceneSessionManager::UpdateRootSceneAvoidArea()
1423 {
1424     UpdateAvoidArea(rootSceneSession_->GetPersistentId());
1425 }
1426 
RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc && func)1427 void SceneSessionManager::RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc&& func)
1428 {
1429     onNotifyAvoidAreaChangeForRootFunc_ = std::move(func);
1430 }
1431 
RegisterNotifyRootSceneOccupiedAreaChangeFunc(NotifyRootSceneOccupiedAreaChangeFunc && func)1432 void SceneSessionManager::RegisterNotifyRootSceneOccupiedAreaChangeFunc(NotifyRootSceneOccupiedAreaChangeFunc&& func)
1433 {
1434     onNotifyOccupiedAreaChangeForRootFunc_ = std::move(func);
1435 }
1436 
GetRootSessionAvoidAreaByType(AvoidAreaType type)1437 AvoidArea SceneSessionManager::GetRootSessionAvoidAreaByType(AvoidAreaType type)
1438 {
1439     if (auto rootSession = GetRootSceneSession()) {
1440         return rootSession->GetAvoidAreaByType(type);
1441     }
1442     return {};
1443 }
1444 
GetSceneSession(int32_t persistentId)1445 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1446 {
1447     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1448     if (auto it = sceneSessionMap_.find(persistentId); it != sceneSessionMap_.end()) {
1449         return it->second;
1450     }
1451     TLOGD(WmsLogTag::DEFAULT, "Not found scene session with id: %{public}d", persistentId);
1452     return nullptr;
1453 }
1454 
IsMainWindowByPersistentId(int32_t persistentId)1455 bool SceneSessionManager::IsMainWindowByPersistentId(int32_t persistentId)
1456 {
1457     if (persistentId <= INVALID_SESSION_ID) {
1458         return false;
1459     }
1460     if (auto sceneSession = GetSceneSession(persistentId)) {
1461         return SessionHelper::IsMainWindow(sceneSession->GetWindowType());
1462     }
1463     return false;
1464 }
1465 
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1466 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1467     const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1468 {
1469     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1470     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1471         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1472             sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1473             SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1474             mainSessions.push_back(sceneSession);
1475         }
1476     }
1477 }
1478 
GetMainSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,std::vector<sptr<SceneSession>> & mainSessions) const1479 void SceneSessionManager::GetMainSessionByAbilityInfo(const AbilityInfoBase& abilityInfo,
1480     std::vector<sptr<SceneSession>>& mainSessions) const
1481 {
1482     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1483     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1484         if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1485             continue;
1486         }
1487         if (sceneSession->GetSessionInfo().bundleName_ == abilityInfo.bundleName &&
1488             sceneSession->GetSessionInfo().moduleName_ == abilityInfo.moduleName &&
1489             sceneSession->GetSessionInfo().abilityName_ == abilityInfo.abilityName &&
1490             sceneSession->GetSessionInfo().appIndex_ == abilityInfo.appIndex) {
1491             mainSessions.push_back(sceneSession);
1492         }
1493     }
1494 }
1495 
GetSceneSessionByIdentityInfo(const SessionIdentityInfo & info)1496 sptr<SceneSession> SceneSessionManager::GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)
1497 {
1498     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1499     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1500         if (!sceneSession) {
1501             return nullptr;
1502         }
1503         if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1504             sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1505             sceneSession->GetSessionInfo().appInstanceKey_ != info.instanceKey_ ||
1506             sceneSession->GetSessionInfo().specifiedFlag_ != info.specifiedFlag_ ||
1507             sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1508             continue;
1509         }
1510         const auto& sessionModuleName = sceneSession->GetSessionInfo().moduleName_;
1511         const auto& sessionAbilityName = sceneSession->GetSessionInfo().abilityName_;
1512         if (info.isAtomicService_) {
1513             if ((sessionModuleName.empty() || sessionModuleName == info.moduleName_) &&
1514                 (sessionAbilityName.empty() || sessionAbilityName == info.abilityName_)) {
1515                 return sceneSession;
1516             }
1517         } else if (sessionModuleName == info.moduleName_ && sessionAbilityName == info.abilityName_) {
1518             return sceneSession;
1519         }
1520     }
1521     return nullptr;
1522 }
1523 
GetSceneSessionByType(WindowType type)1524 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1525 {
1526     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1527     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1528         if (sceneSession && sceneSession->GetWindowType() == type) {
1529             return sceneSession;
1530         }
1531     }
1532     return nullptr;
1533 }
1534 
GetSceneSessionByBundleName(const std::string & bundleName)1535 sptr<SceneSession> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1536 {
1537     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1538     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1539         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1540             return sceneSession;
1541         }
1542     }
1543     return nullptr;
1544 }
1545 
GetSceneSessionVectorByTypeAndDisplayId(WindowType type,uint64_t displayId)1546 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByTypeAndDisplayId(
1547     WindowType type, uint64_t displayId)
1548 {
1549     if (displayId == DISPLAY_ID_INVALID) {
1550         TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1551         return {};
1552     }
1553     std::vector<sptr<SceneSession>> sceneSessionVector;
1554     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1555     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1556         if (sceneSession->GetWindowType() == type &&
1557             sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1558             sceneSessionVector.emplace_back(sceneSession);
1559         }
1560     }
1561     return sceneSessionVector;
1562 }
1563 
GetSceneSessionVectorByType(WindowType type)1564 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
1565 {
1566     std::vector<sptr<SceneSession>> sceneSessionVector;
1567     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1568     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1569         if (sceneSession->GetWindowType() == type) {
1570             sceneSessionVector.emplace_back(sceneSession);
1571         }
1572     }
1573     return sceneSessionVector;
1574 }
1575 
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1576 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1577     sptr<WindowSessionProperty> property)
1578 {
1579     if (sceneSession == nullptr || property == nullptr) {
1580         TLOGD(WmsLogTag::WMS_DIALOG, "Session or property is null");
1581         return WSError::WS_ERROR_NULLPTR;
1582     }
1583     auto parentPersistentId = property->GetParentPersistentId();
1584     sceneSession->SetParentPersistentId(parentPersistentId);
1585     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1586         auto parentSession = GetSceneSession(parentPersistentId);
1587         if (parentSession == nullptr) {
1588             TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1589             return WSError::WS_ERROR_NULLPTR;
1590         }
1591         parentSession->BindDialogSessionTarget(sceneSession);
1592         parentSession->BindDialogToParentSession(sceneSession);
1593         sceneSession->SetParentSession(parentSession);
1594         TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1595             sceneSession->GetPersistentId(), parentPersistentId);
1596     }
1597     return WSError::WS_OK;
1598 }
1599 
CreateSpecificSessionCallback()1600 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1601 {
1602     sptr<SceneSession::SpecificSessionCallback> specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1603     specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1604         return this->RequestSceneSession(sessionInfo, property);
1605     };
1606     specificCb->onDestroy_ = [this](const int32_t persistentId) {
1607         return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1608     };
1609     specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1610         this->ClearDisplayStatusBarTemporarilyFlags();
1611     };
1612     specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1613         this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1614     };
1615     specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1616         return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1617     };
1618     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1619         return this->GetSceneSessionVectorByType(type);
1620     };
1621     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1622         this->UpdateAvoidArea(persistentId);
1623     };
1624     specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1625         return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1626     };
1627     specificCb->onUpdateOccupiedAreaIfNeed_ = [this](int32_t persistentId) {
1628         this->UpdateOccupiedAreaIfNeed(persistentId);
1629     };
1630     specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1631         this->NotifyWindowInfoChange(persistentId, type);
1632     };
1633     specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1634         this->NotifyMMIWindowPidChange(windowId, startMoving);
1635     };
1636     specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1637         this->NotifySessionTouchOutside(persistentId);
1638     };
1639     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1640         return this->GetAINavigationBarArea(displayId);
1641     };
1642     specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1643         this->OnOutsideDownEvent(x, y);
1644     };
1645     specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1646         return this->HandleSecureSessionShouldHide(sceneSession);
1647     };
1648     specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1649         this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1650     };
1651     specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1652         this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1653     };
1654     specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1655         this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1656     };
1657     specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1658         this->UpdateGestureBackEnabled(persistentId);
1659     };
1660     specificCb->onGetSceneSessionByIdCallback_ = [this](int32_t persistentId) {
1661         return this->GetSceneSession(persistentId);
1662     };
1663     return specificCb;
1664 }
1665 
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1666 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1667 {
1668     TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1669     auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1670     if (isSkip) {
1671         if (it == skipSurfaceNodeIds_.end()) {
1672             skipSurfaceNodeIds_.push_back(surfaceNodeId);
1673         } else {
1674             return;
1675         }
1676     } else {
1677         if (it != skipSurfaceNodeIds_.end()) {
1678             skipSurfaceNodeIds_.erase(it);
1679         } else {
1680             return;
1681         }
1682     }
1683     rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1684 }
1685 
AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1686 WMError SceneSessionManager::AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1687 {
1688     auto task = [this, &persistentIds] {
1689         for (const auto persistentId : persistentIds) {
1690             auto session = GetSceneSession(persistentId);
1691             if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1692                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1693                 continue;
1694             }
1695             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] add to virtual screen black list", persistentId);
1696             auto surfaceNode = session->GetSurfaceNode();
1697             if (surfaceNode) {
1698                 auto surfaceNodeId = surfaceNode->GetId();
1699                 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId) == 0) {
1700                     skipSurfaceNodeIds_.push_back(surfaceNodeId);
1701                 }
1702             }
1703             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1704             if (leashWinSurfaceNode) {
1705                 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1706                 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId) == 0) {
1707                     skipSurfaceNodeIds_.push_back(leashWinSurfaceNodeId);
1708                 }
1709             }
1710         }
1711         rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1712         return WMError::WM_OK;
1713     };
1714     return taskScheduler_->PostSyncTask(task, __func__);
1715 }
1716 
RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1717 WMError SceneSessionManager::RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1718 {
1719     auto task = [this, &persistentIds] {
1720         for (const auto persistentId : persistentIds) {
1721             auto session = GetSceneSession(persistentId);
1722             if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1723                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1724                 continue;
1725             }
1726             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] remove from virtual screen black list", persistentId);
1727             auto surfaceNode = session->GetSurfaceNode();
1728             if (surfaceNode) {
1729                 auto surfaceNodeId = surfaceNode->GetId();
1730                 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1731                 if (iter != skipSurfaceNodeIds_.end()) {
1732                     skipSurfaceNodeIds_.erase(iter);
1733                 }
1734             }
1735             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1736             if (leashWinSurfaceNode) {
1737                 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1738                 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId);
1739                 if (iter != skipSurfaceNodeIds_.end()) {
1740                     skipSurfaceNodeIds_.erase(iter);
1741                 }
1742             }
1743         }
1744         rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1745         return WMError::WM_OK;
1746     };
1747     return taskScheduler_->PostSyncTask(task, __func__);
1748 }
1749 
CreateKeyboardSessionCallback()1750 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1751 {
1752     auto keyboardCb = sptr<KeyboardSession::KeyboardSessionCallback>::MakeSptr();
1753     keyboardCb->onGetSceneSession = [this](int32_t persistentId) {
1754         return this->GetSceneSession(persistentId);
1755     };
1756     keyboardCb->onGetFocusedSessionId = [this] {
1757         return this->GetFocusedSessionId();
1758     };
1759     keyboardCb->onCallingSessionIdChange = callingSessionIdChangeFunc_;
1760     keyboardCb->onSystemKeyboardAvoidChange = [this](DisplayId displayId, SystemKeyboardAvoidChangeReason reason) {
1761         this->HandleKeyboardAvoidChange(nullptr, displayId, reason);
1762     };
1763     keyboardCb->onNotifyOccupiedAreaChange = [this](const sptr<OccupiedAreaChangeInfo>& info) {
1764         this->onNotifyOccupiedAreaChangeForRootFunc_(info);
1765     };
1766     return keyboardCb;
1767 }
1768 
CheckWindowId(int32_t windowId,int32_t & pid)1769 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1770 {
1771     if (!SessionPermission::IsSystemCalling()) {
1772         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
1773         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1774     }
1775 
1776     auto task = [this, windowId, &pid] {
1777         pid = INVALID_PID;
1778         auto sceneSession = GetSceneSession(windowId);
1779         if (sceneSession == nullptr) {
1780             TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession(%{public}d) is nullptr", windowId);
1781             return WMError::WM_ERROR_INVALID_WINDOW;
1782         }
1783         pid = sceneSession->GetCallingPid();
1784         TLOGND(WmsLogTag::WMS_EVENT, "Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1785         return WMError::WM_OK;
1786     };
1787     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1788 }
1789 
GetLockScreenZOrder()1790 uint32_t SceneSessionManager::GetLockScreenZOrder()
1791 {
1792     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1793     for (const auto& [persistentId, session] : sceneSessionMap_) {
1794         if (session && session->IsScreenLockWindow()) {
1795             TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: window %{public}d-%{public}d", persistentId,
1796                 session->GetZOrder());
1797             return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
1798                 session->GetZOrder();
1799         }
1800     }
1801     TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
1802     return DEFAULT_LOCK_SCREEN_ZORDER;
1803 }
1804 
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)1805 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
1806     const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
1807 {
1808     if (!SessionPermission::IsSystemCalling()) {
1809         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
1810         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1811     }
1812     auto task = [this, windowId, callingTokenId, &element, extensionAbilityType, &pid] {
1813         pid = INVALID_PID;
1814         auto sceneSession = GetSceneSession(windowId);
1815         if (sceneSession == nullptr) {
1816             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
1817             return WMError::WM_ERROR_INVALID_WINDOW;
1818         }
1819         pid = sceneSession->GetCallingPid();
1820         if (!IsScreenLocked()) {
1821             TLOGND(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
1822             return WMError::WM_OK;
1823         }
1824         if (IsUserAuthPassed()) {
1825             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
1826             return WMError::WM_OK;
1827         }
1828         // 1. check window whether can show on main window
1829         if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
1830             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
1831             return WMError::WM_OK;
1832         }
1833         // 2. check permission
1834         if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
1835             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
1836                 callingTokenId);
1837             return WMError::WM_ERROR_INVALID_PERMISSION;
1838         }
1839         TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: pass");
1840         return WMError::WM_OK;
1841     };
1842 
1843     std::ostringstream ss;
1844     ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
1845     return taskScheduler_->PostSyncTask(task, ss.str());
1846 }
1847 
1848 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)1849 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
1850 {
1851     taskScheduler_->PostSyncTask([this, &windowIds] {
1852         // check every window
1853         for (auto windowId : windowIds) {
1854             auto sceneSession = GetSceneSession(windowId);
1855             if (!sceneSession) {
1856                 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
1857                 continue;
1858             }
1859             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
1860             sceneSession->OnNotifyAboveLockScreen();
1861         }
1862         return WMError::WM_OK;
1863     }, __func__);
1864 }
1865 
GetKeyboardSession(DisplayId displayId,bool isSystemKeyboard)1866 sptr<SceneSession> SceneSessionManager::GetKeyboardSession(DisplayId displayId, bool isSystemKeyboard)
1867 {
1868     if (displayId == DISPLAY_ID_INVALID) {
1869         TLOGE(WmsLogTag::WMS_KEYBOARD, "displayId is invalid.");
1870         return nullptr;
1871     }
1872     sptr<SceneSession> keyboardSession = nullptr;
1873     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1874     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1875         if (sceneSession && sceneSession->GetScreenId() == displayId &&
1876             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
1877             sceneSession->IsSystemKeyboard() == isSystemKeyboard) {
1878             keyboardSession = sceneSession;
1879             break;
1880         }
1881     }
1882     return keyboardSession;
1883 }
1884 
HandleKeyboardAvoidChange(const sptr<SceneSession> & sceneSession,DisplayId displayId,SystemKeyboardAvoidChangeReason reason)1885 void SceneSessionManager::HandleKeyboardAvoidChange(const sptr<SceneSession>& sceneSession, DisplayId displayId,
1886     SystemKeyboardAvoidChangeReason reason)
1887 {
1888     if (!systemConfig_.IsPcWindow()) {
1889         TLOGI(WmsLogTag::WMS_KEYBOARD, "this device is not pc.");
1890         return;
1891     }
1892     switch (reason) {
1893         // if the system keyboard's avoid area is active first, deactivate the other keyboard's avoid area
1894         case SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED: {
1895             if (!sceneSession || sceneSession->IsSystemKeyboard()) {
1896                 return;
1897             }
1898             sptr<SceneSession> systemKeyboardSession = GetKeyboardSession(displayId, true);
1899             if (systemKeyboardSession && systemKeyboardSession->IsSessionForeground() &&
1900                 systemKeyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
1901                 sceneSession->ActivateKeyboardAvoidArea(false, false);
1902             }
1903             break;
1904         }
1905         /*
1906          * activate the system keyboard's avoid area, while it is showing or it's gravity is bottom
1907          * and deactivate other keyboard's avoid area
1908          */
1909         case SystemKeyboardAvoidChangeReason::KEYBOARD_SHOW:
1910         case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_BOTTOM: {
1911             UpdateKeyboardAvoidAreaActive(true);
1912             break;
1913         }
1914         /*
1915          * when the system keyboard is hiden, disconnect or it's gravity is float
1916          * check for whether other keyboard can be avoided: if yes, avoids the other keyboard
1917          *                                                  if no, restores the system keyboard
1918          */
1919         case SystemKeyboardAvoidChangeReason::KEYBOARD_HIDE:
1920         case SystemKeyboardAvoidChangeReason::KEYBOARD_DISCONNECT:
1921         case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_FLOAT: {
1922             bool keyboardRecalculate = false;
1923             if (auto keyboardSession = GetKeyboardSession(displayId, false)) {
1924                 if (keyboardSession->IsSessionForeground() &&
1925                     keyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
1926                     keyboardRecalculate = true;
1927                 }
1928                 keyboardSession->ActivateKeyboardAvoidArea(true, keyboardRecalculate);
1929             }
1930             if (auto sysKeyboardSession = GetKeyboardSession(displayId, true)) {
1931                 sysKeyboardSession->ActivateKeyboardAvoidArea(false, !keyboardRecalculate);
1932             }
1933             break;
1934         }
1935         default:
1936             break;
1937     }
1938 }
1939 
UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)1940 void SceneSessionManager::UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)
1941 {
1942     const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
1943     if (keyboardSessionVec.empty()) {
1944         TLOGI(WmsLogTag::WMS_KEYBOARD, "there is no keyboard window in the map");
1945         return;
1946     }
1947     for (const auto& keyboardSession : keyboardSessionVec) {
1948         if (!keyboardSession) {
1949             continue;
1950         }
1951         if (keyboardSession->IsSystemKeyboard()) {
1952             keyboardSession->ActivateKeyboardAvoidArea(systemKeyboardAvoidAreaActive, false);
1953         } else {
1954             keyboardSession->ActivateKeyboardAvoidArea(!systemKeyboardAvoidAreaActive, false);
1955         }
1956     }
1957 }
1958 
RequestKeyboardPanelSession(const std::string & panelName,uint64_t displayId)1959 sptr<SceneSession> SceneSessionManager::RequestKeyboardPanelSession(const std::string& panelName, uint64_t displayId)
1960 {
1961     SessionInfo panelInfo = {
1962         .bundleName_ = panelName,
1963         .moduleName_ = panelName,
1964         .abilityName_ = panelName,
1965         .isSystem_ = true,
1966         .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1967         .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1968         .screenId_ = displayId,
1969         .isRotable_ = true,
1970     };
1971     if (systemConfig_.IsPcWindow()) {
1972         panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1973         TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1974     } else {
1975         TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1976     }
1977     return RequestSceneSession(panelInfo, nullptr);
1978 }
1979 
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1980 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1981 {
1982     if (!isKeyboardPanelEnabled_) {
1983         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1984         return;
1985     }
1986     if (keyboardSession == nullptr) {
1987         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1988         return;
1989     }
1990     const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
1991     sptr<SceneSession> panelSession;
1992     for (const auto& session : panelVec) {
1993         if (session && session->IsSystemKeyboard() == keyboardSession->IsSystemKeyboard()) {
1994             panelSession = session;
1995             break;
1996         }
1997     }
1998     /*
1999      * Only 2 scenarios of panelSession is nullptr:
2000      * 1: neither keyboard panel session nor system keyboard panel session is created.
2001      * 2: a panel session has been created already, but it's isSystemKeyboard is not match with the keyboardSesion's
2002      */
2003     if (panelSession == nullptr) {
2004         if (panelVec.size() >= 2) { // 2 is max number of keyboard panel, one input method and one system keyboard
2005             TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
2006             return;
2007         }
2008         std::string panelName = keyboardSession->IsSystemKeyboard() ? "SCBSystemKeyboardPanel" : "SCBKeyboardPanel";
2009         panelSession = RequestKeyboardPanelSession(panelName,
2010             static_cast<uint64_t>(keyboardSession->GetSessionProperty()->GetDisplayId()));
2011         if (panelSession == nullptr) {
2012             TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
2013             return;
2014         }
2015     } else {
2016         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId: %{public}d",
2017             panelSession->GetPersistentId());
2018     }
2019     panelSession->SetIsSystemKeyboard(keyboardSession->IsSystemKeyboard());
2020     keyboardSession->BindKeyboardPanelSession(panelSession);
2021     panelSession->BindKeyboardSession(keyboardSession);
2022     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
2023         panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
2024 }
2025 
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2026 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
2027     sptr<WindowSessionProperty> property)
2028 {
2029     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
2030     sptr<SceneSession> sceneSession = nullptr;
2031     if (sessionInfo.isSystem_) {
2032         sceneSession = new SCBSystemSession(sessionInfo, specificCb);
2033         TLOGI(WmsLogTag::DEFAULT, "[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
2034     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2035         sceneSession = new MainSession(sessionInfo, specificCb);
2036         TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
2037     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
2038         sceneSession = new SubSession(sessionInfo, specificCb);
2039         TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
2040     } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2041         sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
2042         sceneSession = new KeyboardSession(sessionInfo, specificCb, keyboardCb);
2043         sceneSession->SetIsSystemKeyboard(property->IsSystemKeyboard());
2044         CreateKeyboardPanelSession(sceneSession);
2045         HandleKeyboardAvoidChange(sceneSession, sceneSession->GetScreenId(),
2046             SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED);
2047         TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
2048     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
2049         sceneSession = new SystemSession(sessionInfo, specificCb);
2050         TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
2051     } else {
2052         TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
2053     }
2054     if (sceneSession != nullptr) {
2055         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
2056         sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
2057         sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
2058             return this->GetAppForceLandscapeConfig(bundleName);
2059         });
2060         sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
2061             this->UpdatePrivateStateAndNotify(persistentId);
2062         });
2063         sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
2064             this->NotifyVisibleChange(persistentId);
2065         });
2066         sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
2067             return this->IsLastFrameLayoutFinished(isLayoutFinished);
2068         });
2069         sceneSession->SetIsAINavigationBarAvoidAreaValidFunc([this](const AvoidArea& avoidArea, int32_t sessionBottom) {
2070             return CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea, sessionBottom);
2071         });
2072         sceneSession->RegisterGetStatusBarAvoidHeightFunc([this](WSRect& barArea) {
2073             return this->GetStatusBarAvoidHeight(barArea);
2074         });
2075         sceneSession->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
2076             return this->GetStatusBarConstantlyShow(displayId, isVisible);
2077         });
2078         DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2079         GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
2080         sceneSession->SetAppDragResizeType(dragResizeType);
2081         sceneSession->SetSingleHandTransform(singleHandTransform_);
2082         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
2083             sceneSession->GetPersistentId(), sceneSession->GetSessionProperty()->GetDisplayId());
2084     }
2085     return sceneSession;
2086 }
2087 
GetEffectiveDragResizeType(DragResizeType & dragResizeType)2088 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
2089 {
2090     if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2091         return;
2092     }
2093     if (systemConfig_.freeMultiWindowSupport_) {
2094         dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
2095     } else {
2096         dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
2097     }
2098 }
2099 
SetGlobalDragResizeType(DragResizeType dragResizeType)2100 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
2101 {
2102     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2103     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2104         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2105         return WMError::WM_ERROR_INVALID_PERMISSION;
2106     }
2107     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2108     globalDragResizeType_ = dragResizeType;
2109     taskScheduler_->PostAsyncTask([this] {
2110         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2111         for (const auto& [_, sceneSession] : sceneSessionMap_) {
2112             if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2113                 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
2114                 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2115                 GetAppDragResizeType(bundleName, appDragResizeType);
2116                 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2117                     "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
2118                 sceneSession->SetAppDragResizeType(appDragResizeType);
2119             }
2120         }
2121     }, __func__);
2122     return WMError::WM_OK;
2123 }
2124 
GetGlobalDragResizeType(DragResizeType & dragResizeType)2125 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
2126 {
2127     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2128     dragResizeType = globalDragResizeType_;
2129     GetEffectiveDragResizeType(dragResizeType);
2130     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2131     return WMError::WM_OK;
2132 }
2133 
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)2134 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
2135 {
2136     TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2137         dragResizeType, bundleName.c_str());
2138     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2139         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2140         return WMError::WM_ERROR_INVALID_PERMISSION;
2141     }
2142     return SetAppDragResizeTypeInner(bundleName, dragResizeType);
2143 }
2144 
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)2145 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
2146 {
2147     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2148         dragResizeType, bundleName.c_str());
2149     if (bundleName.empty()) {
2150         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2151         return WMError::WM_ERROR_INVALID_PARAM;
2152     }
2153     std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
2154     appDragResizeTypeMap_[bundleName] = dragResizeType;
2155     GetAppDragResizeTypeInner(bundleName, dragResizeType);
2156     taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
2157         auto sceneSession = GetSceneSessionByBundleName(bundleName);
2158         if (sceneSession != nullptr) {
2159             TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2160                 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
2161             sceneSession->SetAppDragResizeType(dragResizeType);
2162         }
2163     }, __func__);
2164     return WMError::WM_OK;
2165 }
2166 
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)2167 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
2168 {
2169     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2170     return GetAppDragResizeTypeInner(bundleName, dragResizeType);
2171 }
2172 
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)2173 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
2174 {
2175     if (bundleName.empty()) {
2176         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2177         return WMError::WM_ERROR_INVALID_PARAM;
2178     }
2179     if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2180         TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
2181         dragResizeType = globalDragResizeType_;
2182         return WMError::WM_OK;
2183     }
2184     dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2185     if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
2186         dragResizeType = iter->second;
2187     }
2188     GetEffectiveDragResizeType(dragResizeType);
2189     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2190         dragResizeType, bundleName.c_str());
2191     return WMError::WM_OK;
2192 }
2193 
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)2194 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
2195 {
2196     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
2197         if (auto session = GetSceneSession(sessionInfo.persistentId_)) {
2198             TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
2199             return session;
2200         }
2201 
2202         if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2203             TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
2204                 "abilityName: %{public}s, appIndex: %{public}d",
2205                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2206                 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
2207             SessionIdentityInfo identityInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_,
2208                 sessionInfo.abilityName_, sessionInfo.appIndex_, sessionInfo.appInstanceKey_, sessionInfo.windowType_,
2209                 sessionInfo.isAtomicService_ };
2210             auto sceneSession = GetSceneSessionByIdentityInfo(identityInfo);
2211             bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
2212                 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
2213             if (isSingleStart) {
2214                 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
2215                     sessionInfo.persistentId_);
2216                 return sceneSession;
2217             }
2218         }
2219     }
2220     return nullptr;
2221 }
2222 
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2223 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
2224     sptr<WindowSessionProperty> property)
2225 {
2226     auto task = [this, sessionInfo, property, where = __func__] {
2227         if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
2228             UpdateSessionDisplayIdBySessionInfo(session, sessionInfo);
2229             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2230             return session;
2231         }
2232         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
2233             "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
2234             where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2235             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
2236             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
2237         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
2238         if (sceneSession == nullptr) {
2239             TLOGNE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
2240             return sceneSession;
2241         }
2242         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2243             WindowHelper::IsMainWindow(sceneSession->GetWindowType()) &&
2244             MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2245             MultiInstanceManager::GetInstance().FillInstanceKeyIfNeed(sceneSession);
2246         }
2247         LOCK_GUARD_EXPR(SCENE_GUARD, InitSceneSession(sceneSession, sessionInfo, property));
2248         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2249             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
2250                 where, sceneSession->GetSessionInfo().ancoSceneState);
2251             bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
2252             const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
2253             if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
2254                 TLOGNI(WmsLogTag::WMS_LIFE,
2255                     "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
2256                     where, reusedSceneSession->GetPersistentId(),
2257                     reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
2258                 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
2259                 return reusedSceneSession;
2260             }
2261             if (isPreHandleSuccess) {
2262                 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
2263                 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
2264             }
2265         }
2266         {
2267             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2268             sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
2269             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2270                 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2271                 MultiInstanceManager::GetInstance().IncreaseInstanceKeyRefCount(sceneSession);
2272             }
2273         }
2274         PerformRegisterInRequestSceneSession(sceneSession);
2275         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2276         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id: %{public}d, type: %{public}d, instanceKey: %{public}s, "
2277                "displayId: %{public}" PRIu64, where, sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
2278                sceneSession->GetAppInstanceKey().c_str(), sceneSession->GetSessionProperty()->GetDisplayId());
2279         return sceneSession;
2280     };
2281     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
2282 }
2283 
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)2284 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
2285     const sptr<WindowSessionProperty>& property)
2286 {
2287     auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
2288     DisplayId currDisplayId = DISPLAY_ID_INVALID;
2289     if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
2290         currDisplayId = sessionInfo.screenId_;
2291     } else if (callerSession) {
2292         currDisplayId = callerSession->GetSessionProperty()->GetDisplayId();
2293     }
2294     sceneSession->GetSessionProperty()->SetDisplayId(currDisplayId);
2295     sceneSession->SetScreenId(currDisplayId);
2296     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "synchronous screenId with displayId %{public}" PRIu64, currDisplayId);
2297 
2298     sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
2299     sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
2300     if (sessionInfo.isSystem_) {
2301         sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
2302         sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
2303         auto rootContext = rootSceneContextWeak_.lock();
2304         sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
2305     } else {
2306         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
2307             "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
2308             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2309             sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
2310     }
2311     RegisterSessionExceptionFunc(sceneSession);
2312     RegisterVisibilityChangedDetectFunc(sceneSession);
2313     // Skip FillSessionInfo when atomicService free-install start.
2314     if (!IsAtomicServiceFreeInstall(sessionInfo)) {
2315         FillSessionInfo(sceneSession);
2316     }
2317     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
2318     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2319         WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
2320     }
2321     if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
2322         sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
2323     }
2324     sceneSession->SetSystemConfig(systemConfig_);
2325     sceneSession->SetSnapshotScale(snapshotScale_);
2326     UpdateParentSessionForDialog(sceneSession, property);
2327     std::string key = sessionInfo.bundleName_ + "_" + sessionInfo.moduleName_ + "_" + sessionInfo.abilityName_ + "_" +
2328         std::to_string(sessionInfo.appIndex_);
2329     if (sessionLockedStateCacheSet_.find(key) != sessionLockedStateCacheSet_.end()) {
2330         sceneSession->NotifySessionLockStateChange(true);
2331     }
2332 }
2333 
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)2334 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
2335 {
2336     taskScheduler_->PostAsyncTask([abilityName = sessionInfo.abilityName_,
2337         bundleName = sessionInfo.bundleName_, toScreenId = sessionInfo.screenId_, action, fromScreenId] {
2338         sptr<DisplayChangeInfo> info = sptr<DisplayChangeInfo>::MakeSptr();
2339         info->action_ = action;
2340         info->abilityName_ = std::move(abilityName);
2341         info->bundleName_ = std::move(bundleName);
2342         info->toScreenId_ = toScreenId;
2343         info->fromScreenId_ = fromScreenId;
2344         ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
2345         TLOGNI(WmsLogTag::DMS, "Notify ability %{public}s bundle %{public}s update toScreen id: %{public}" PRIu64,
2346             info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
2347     }, __func__);
2348 }
2349 
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)2350 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
2351 {
2352     RegisterSessionSnapshotFunc(sceneSession);
2353     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
2354     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
2355     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
2356     RegisterGetStateFromManagerFunc(sceneSession);
2357     RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
2358     RegisterAcquireRotateAnimationConfigFunc(sceneSession);
2359     RegisterRequestVsyncFunc(sceneSession);
2360 }
2361 
UpdateSceneSessionWant(const SessionInfo & sessionInfo)2362 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
2363 {
2364     if (sessionInfo.persistentId_ != 0) {
2365         auto session = GetSceneSession(sessionInfo.persistentId_);
2366         if (session != nullptr && sessionInfo.want != nullptr) {
2367             TLOGI(WmsLogTag::WMS_MAIN, "Get session id:%{public}d", sessionInfo.persistentId_);
2368             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
2369                 session->SetSessionInfoWant(sessionInfo.want);
2370                 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
2371             } else {
2372                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
2373             }
2374         } else {
2375             TLOGI(WmsLogTag::WMS_MAIN, "Get session fail(%{public}d), id:%{public}d",
2376                 session == nullptr, sessionInfo.persistentId_);
2377         }
2378     } else {
2379         TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
2380     }
2381 }
2382 
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2383 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2384 {
2385     if (session != nullptr && session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2386         FillSessionInfo(session);
2387         if (CheckCollaboratorType(session->GetCollaboratorType())) {
2388             PreHandleCollaborator(session, persistentId);
2389         }
2390     }
2391 }
2392 
SetAbilitySessionInfo(const sptr<SceneSession> & sceneSession)2393 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& sceneSession)
2394 {
2395     const auto& sessionInfo = sceneSession->GetSessionInfo();
2396     auto abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
2397     abilitySessionInfo->sessionToken = sptr<ISession>(sceneSession)->AsObject();
2398     abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2399         std::chrono::system_clock::now()).time_since_epoch().count());
2400     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2401     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2402         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2403     abilitySessionInfo->persistentId = sceneSession->GetPersistentId();
2404     abilitySessionInfo->requestCode = sessionInfo.requestCode;
2405     abilitySessionInfo->resultCode = sessionInfo.resultCode;
2406     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2407     abilitySessionInfo->startSetting = sessionInfo.startSetting;
2408     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2409     abilitySessionInfo->userId = currentUserId_;
2410     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2411     abilitySessionInfo->processOptions = sessionInfo.processOptions;
2412     abilitySessionInfo->requestId = sessionInfo.requestId;
2413     if (sessionInfo.want != nullptr) {
2414         abilitySessionInfo->want = *sessionInfo.want;
2415     } else {
2416         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2417             sessionInfo.moduleName_);
2418     }
2419     int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2420     bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2421     if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2422         TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2423             appIndex, sessionInfo.appIndex_);
2424     }
2425     if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2426         TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2427         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2428     }
2429     abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2430         static_cast<int>(sceneSession->GetSessionProperty()->GetDisplayId()));
2431     abilitySessionInfo->instanceKey = sessionInfo.appInstanceKey_;
2432     if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2433         sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2434         abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2435     } else {
2436         TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2437     }
2438     return abilitySessionInfo;
2439 }
2440 
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2441 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2442 {
2443     if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2444         isPrepareTerminate = false;
2445         TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2446         return WSError::WS_OK;
2447     }
2448     auto sceneSession = GetSceneSession(persistentId);
2449     if (sceneSession == nullptr) {
2450         TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2451         isPrepareTerminate = false;
2452         return WSError::WS_ERROR_NULLPTR;
2453     }
2454     auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2455     auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2456         PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2457     TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2458         "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2459     return WSError::WS_OK;
2460 }
2461 
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)2462 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
2463 {
2464     auto task = [this, weakSceneSession = wptr(sceneSession), isNewActive]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
2465         sptr<SceneSession> sceneSession = weakSceneSession.promote();
2466         if (sceneSession == nullptr) {
2467             TLOGNE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2468             return WSError::WS_ERROR_NULLPTR;
2469         }
2470         if (!Session::IsScbCoreEnabled()) {
2471             sceneSession->SetForegroundInteractiveStatus(true);
2472         }
2473         auto persistentId = sceneSession->GetPersistentId();
2474         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2475         TLOGNI(WmsLogTag::WMS_MAIN,
2476             "Request active id:%{public}d, system:%{public}d, isNewActive:%{public}d, requestId:%{public}d",
2477             persistentId, sceneSession->GetSessionInfo().isSystem_,
2478             isNewActive, sceneSession->GetSessionInfo().requestId);
2479         if (!GetSceneSession(persistentId)) {
2480             TLOGNE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2481             return WSError::WS_ERROR_INVALID_SESSION;
2482         }
2483         auto ret = RequestSceneSessionActivationInner(sceneSession, isNewActive);
2484         if (ret == WSError::WS_OK) {
2485             sceneSession->SetExitSplitOnBackground(false);
2486         }
2487         abilityInfoMap_.clear(); // clear cache after terminate
2488         return ret;
2489     };
2490     std::string taskName = "RequestSceneSessionActivation:PID:" +
2491         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2492     taskScheduler_->PostAsyncTask(task, taskName);
2493     return WSError::WS_OK;
2494 }
2495 
IsKeyboardForeground()2496 bool SceneSessionManager::IsKeyboardForeground()
2497 {
2498     bool isKeyboardForeground = false;
2499     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2500     for (const auto& [_, sceneSession] : sceneSessionMap_) {
2501         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2502             isKeyboardForeground = sceneSession->IsSessionForeground();
2503             break;
2504         }
2505     }
2506     return isKeyboardForeground;
2507 }
2508 
RequestInputMethodCloseKeyboard(const int32_t persistentId)2509 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
2510 {
2511     auto sceneSession = GetSceneSession(persistentId);
2512     if (sceneSession == nullptr) {
2513         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
2514         return;
2515     }
2516     // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
2517     if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
2518         !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
2519         TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
2520             persistentId, sceneSession->GetSessionState());
2521         sceneSession->RequestHideKeyboard(true);
2522     }
2523 }
2524 
StartUIAbilityBySCBTimeoutCheck(const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const uint32_t & windowStateChangeReason,bool & isColdStart)2525 int32_t SceneSessionManager::StartUIAbilityBySCBTimeoutCheck(const sptr<AAFwk::SessionInfo>& abilitySessionInfo,
2526     const uint32_t& windowStateChangeReason, bool& isColdStart)
2527 {
2528     std::shared_ptr<int32_t> retCode = std::make_shared<int32_t>(0);
2529     std::shared_ptr<bool> coldStartFlag = std::make_shared<bool>(false);
2530     bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([abilitySessionInfo, coldStartFlag, retCode,
2531         windowStateChangeReason] {
2532         auto result = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo,
2533             *coldStartFlag, windowStateChangeReason);
2534         *retCode = static_cast<int32_t>(result);
2535         TLOGNI(WmsLogTag::WMS_LIFE, "start ui ability retCode: %{public}d", *retCode);
2536     }, START_UI_ABILITY_TIMEOUT);
2537 
2538     if (isTimeout) {
2539         TLOGE(WmsLogTag::WMS_LIFE, "start ui ability timeout, currentUserId: %{public}d", currentUserId_.load());
2540         return static_cast<int32_t>(WSError::WS_ERROR_START_UI_ABILITY_TIMEOUT);
2541     }
2542     isColdStart = *coldStartFlag;
2543     return *retCode;
2544 }
2545 
StartUIAbilityBySCB(sptr<SceneSession> & sceneSession)2546 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& sceneSession)
2547 {
2548     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
2549     return StartUIAbilityBySCB(abilitySessionInfo);
2550 }
2551 
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)2552 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
2553 {
2554     bool isColdStart = false;
2555     return StartUIAbilityBySCBTimeoutCheck(abilitySessionInfo,
2556         static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
2557 }
2558 
ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession> & sceneSession,bool visibility,bool isFromClient)2559 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession>& sceneSession,
2560     bool visibility, bool isFromClient)
2561 {
2562     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
2563     if (!isFromClient) {
2564         sceneSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
2565     }
2566     return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
2567 }
2568 
RequestSceneSessionActivationInner(sptr<SceneSession> & sceneSession,bool isNewActive)2569 WSError SceneSessionManager::RequestSceneSessionActivationInner(
2570     sptr<SceneSession>& sceneSession, bool isNewActive)
2571 {
2572     auto persistentId = sceneSession->GetPersistentId();
2573     RequestInputMethodCloseKeyboard(persistentId);
2574     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2575         sceneSession->SetIsStarting(true);
2576         sceneSession->SetStartingBeforeVisible(true);
2577     }
2578     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) && sceneSession->IsFocusedOnShow()) {
2579         if (Session::IsScbCoreEnabled()) {
2580             if (sceneSession->IsVisibleForeground()) {
2581                 RequestSessionFocusImmediately(persistentId);
2582             } else {
2583                 PostProcessFocusState state = { true, true, true, FocusChangeReason::SCB_START_APP };
2584                 sceneSession->SetPostProcessFocusState(state);
2585             }
2586         } else {
2587             RequestSessionFocusImmediately(persistentId);
2588         }
2589     }
2590     if (sceneSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2591         FillSessionInfo(sceneSession);
2592         if (!PreHandleCollaborator(sceneSession, persistentId)) {
2593             TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
2594                 persistentId, sceneSession->GetSessionInfo().ancoSceneState);
2595             ExceptionInfo exceptionInfo;
2596             exceptionInfo.needRemoveSession = true;
2597             sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
2598             return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
2599         }
2600     }
2601     sceneSession->NotifyActivation();
2602     auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2603     sceneSessionInfo->isNewWant = isNewActive;
2604     if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2605         sceneSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, sceneSessionInfo->persistentId);
2606         sceneSessionInfo->collaboratorType = sceneSession->GetCollaboratorType();
2607     }
2608     TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
2609         "module: %{public}s, uri: %{public}s, appIndex: %{public}d, requestId:%{public}d", persistentId,
2610         sceneSessionInfo->want.GetElement().GetAbilityName().c_str(),
2611         sceneSessionInfo->want.GetElement().GetBundleName().c_str(),
2612         sceneSessionInfo->want.GetElement().GetModuleName().c_str(),
2613         sceneSessionInfo->want.GetElement().GetURI().c_str(),
2614         sceneSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0),
2615         sceneSessionInfo->requestId);
2616     int32_t errCode = ERR_OK;
2617     bool isColdStart = false;
2618     if (!systemConfig_.backgroundswitch || sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc()) {
2619         TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
2620             static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
2621         errCode = StartUIAbilityBySCBTimeoutCheck(sceneSessionInfo,
2622             static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
2623     } else {
2624         TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
2625             isNewActive, sceneSession->GetSessionState());
2626         if (isNewActive || sceneSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
2627             sceneSession->GetSessionState() == SessionState::STATE_END) {
2628             TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
2629                 static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
2630             errCode = StartUIAbilityBySCBTimeoutCheck(sceneSessionInfo,
2631                 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
2632         } else {
2633             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
2634             sceneSession->NotifySessionForeground(1, true);
2635         }
2636     }
2637     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2638         WindowInfoReporter::GetInstance().InsertShowReportInfo(sceneSession->GetSessionInfo().bundleName_);
2639     }
2640     NotifyCollaboratorAfterStart(sceneSession, sceneSessionInfo);
2641     if (errCode != ERR_OK) {
2642         TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
2643         ExceptionInfo exceptionInfo;
2644         exceptionInfo.needRemoveSession = true;
2645         sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo, false, true);
2646         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
2647             startUIAbilityErrorFunc_(
2648                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
2649         }
2650     }
2651     if (isColdStart) {
2652         TLOGI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
2653             sceneSessionInfo->identityToken.c_str(), sceneSession->GetSessionInfo().bundleName_.c_str());
2654         sceneSession->SetClientIdentityToken(sceneSessionInfo->identityToken);
2655         sceneSession->ResetSessionConnectState();
2656         sceneSession->ResetIsActive();
2657     }
2658     return WSError::WS_OK;
2659 }
2660 
NotifyCollaboratorAfterStart(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> & sceneSessionInfo)2661 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& sceneSession,
2662     sptr<AAFwk::SessionInfo>& sceneSessionInfo)
2663 {
2664     if (sceneSession == nullptr || sceneSessionInfo == nullptr) {
2665         return;
2666     }
2667     if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2668         NotifyLoadAbility(sceneSession->GetCollaboratorType(),
2669             sceneSessionInfo, sceneSession->GetSessionInfo().abilityInfo);
2670         NotifyUpdateSessionInfo(sceneSession);
2671         NotifyMoveSessionToForeground(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
2672         sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2673     }
2674 }
2675 
IsPcSceneSessionLifecycle(const sptr<SceneSession> & sceneSession)2676 bool SceneSessionManager::IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)
2677 {
2678     bool isPcAppInPad = sceneSession->GetSessionProperty()->GetIsPcAppInPad();
2679     bool isAppSupportPhoneInPc = sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc();
2680     return (systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || (isPcAppInPad && !IsScreenLocked());
2681 }
2682 
InitSnapshotCache()2683 void SceneSessionManager::InitSnapshotCache()
2684 {
2685     const static std::unordered_map<WindowUIType, std::size_t> SNAPSHOT_CACHE_CAPACITY_MAP = {
2686         {WindowUIType::PC_WINDOW,      MAX_SNAPSHOT_IN_RECENT_PC},
2687         {WindowUIType::PAD_WINDOW,     MAX_SNAPSHOT_IN_RECENT_PAD},
2688         {WindowUIType::PHONE_WINDOW,   MAX_SNAPSHOT_IN_RECENT_PHONE},
2689         {WindowUIType::INVALID_WINDOW, MAX_SNAPSHOT_IN_RECENT_PHONE},
2690     };
2691 
2692     snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(WindowUIType::INVALID_WINDOW);
2693     auto uiType = systemConfig_.windowUIType_;
2694     if (SNAPSHOT_CACHE_CAPACITY_MAP.find(uiType) != SNAPSHOT_CACHE_CAPACITY_MAP.end()) {
2695         snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(uiType);
2696     }
2697     TLOGI(WmsLogTag::WMS_PATTERN, "type: %{public}hhu, capacity: %{public}zu", uiType, snapshotCapacity_);
2698     snapshotLruCache_ = std::make_unique<LruCache>(snapshotCapacity_);
2699 }
2700 
PutSnapshotToCache(int32_t persistentId)2701 void SceneSessionManager::PutSnapshotToCache(int32_t persistentId)
2702 {
2703     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2704     if (int32_t removedCacheId = snapshotLruCache_->Put(persistentId);
2705         removedCacheId != UNDEFINED_REMOVED_KEY) {
2706         if (auto removedCacheSession = GetSceneSession(removedCacheId)) {
2707             removedCacheSession->ResetSnapshot();
2708         } else {
2709             TLOGW(WmsLogTag::WMS_PATTERN, "removedCacheSession:%{public}d nullptr", removedCacheId);
2710         }
2711     }
2712 }
2713 
VisitSnapshotFromCache(int32_t persistentId)2714 void SceneSessionManager::VisitSnapshotFromCache(int32_t persistentId)
2715 {
2716     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2717     if (!snapshotLruCache_->Visit(persistentId)) {
2718         TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d not in cache", persistentId);
2719     }
2720 }
2721 
RemoveSnapshotFromCache(int32_t persistentId)2722 void SceneSessionManager::RemoveSnapshotFromCache(int32_t persistentId)
2723 {
2724     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2725     snapshotLruCache_->Remove(persistentId);
2726     if (auto sceneSession = GetSceneSession(persistentId)) {
2727         sceneSession->ResetSnapshot();
2728     }
2729 }
2730 
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)2731 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2732     const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2733 {
2734     auto task = [this, weakSceneSession = wptr(sceneSession), isDelegator, isToDesktop, isSaveSnapshot] {
2735         auto sceneSession = weakSceneSession.promote();
2736         if (sceneSession == nullptr) {
2737             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr");
2738             return WSError::WS_ERROR_NULLPTR;
2739         }
2740         auto persistentId = sceneSession->GetPersistentId();
2741         TLOGNI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2742             "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2743             persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2744         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2745 
2746         if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) {
2747             TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId);
2748             if (!sceneSession->UpdateInteractiveInner(false)) {
2749                 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId);
2750             }
2751         }
2752         sceneSession->SetActive(false);
2753 
2754         if (isToDesktop) {
2755             sceneSession->EditSessionInfo().callerToken_ = nullptr;
2756             sceneSession->EditSessionInfo().callingTokenId_ = 0;
2757         }
2758 
2759         sceneSession->SetSaveSnapshotCallback([this, persistentId]() {
2760             this->PutSnapshotToCache(persistentId);
2761         });
2762         sceneSession->BackgroundTask(isSaveSnapshot);
2763         listenerController_->NotifySessionLifecycleEvent(
2764             ISessionLifecycleListener::SessionLifecycleEvent::BACKGROUND, sceneSession->GetSessionInfo());
2765         if (!GetSceneSession(persistentId)) {
2766             TLOGNE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2767             return WSError::WS_ERROR_INVALID_SESSION;
2768         }
2769         if (persistentId == brightnessSessionId_) {
2770             auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
2771             auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
2772             UpdateBrightness(focusedSessionId);
2773         }
2774         if (IsPcSceneSessionLifecycle(sceneSession)) {
2775             TLOGNI(WmsLogTag::WMS_MAIN, "Notify session background: %{public}d", persistentId);
2776             sceneSession->NotifySessionBackground(1, true, true);
2777         } else {
2778             TLOGNI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2779                 persistentId, static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
2780             auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2781             if (!isDelegator) {
2782                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, false,
2783                     static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
2784             } else {
2785                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, true,
2786                     static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
2787             }
2788         }
2789 
2790         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2791             WindowInfoReporter::GetInstance().InsertHideReportInfo(sceneSession->GetSessionInfo().bundleName_);
2792         }
2793         return WSError::WS_OK;
2794     };
2795     std::string taskName = "RequestSceneSessionBackground:PID:" +
2796         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2797     taskScheduler_->PostAsyncTask(task, taskName);
2798     return WSError::WS_OK;
2799 }
2800 
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2801 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2802 {
2803     taskScheduler_->PostAsyncTask([this, weakSceneSession = wptr(sceneSession), interactive] {
2804         auto sceneSession = weakSceneSession.promote();
2805         if (sceneSession == nullptr) {
2806             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
2807             return;
2808         }
2809         auto persistentId = sceneSession->GetPersistentId();
2810         TLOGNI(WmsLogTag::WMS_LIFE, "NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2811         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2812         if (!GetSceneSession(persistentId)) {
2813             TLOGNE(WmsLogTag::WMS_LIFE, "session is invalid with %{public}d", persistentId);
2814             return;
2815         }
2816         sceneSession->NotifyForegroundInteractiveStatus(interactive);
2817     }, __func__);
2818 }
2819 
DestroyDialogWithMainWindow(const sptr<SceneSession> & sceneSession)2820 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& sceneSession)
2821 {
2822     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2823     if (sceneSession == nullptr) {
2824         TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2825         return WSError::WS_ERROR_NULLPTR;
2826     }
2827     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2828         TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", sceneSession->GetPersistentId());
2829         const auto& dialogVec = sceneSession->GetDialogVector();
2830         for (const auto& dialog : dialogVec) {
2831             if (dialog == nullptr) {
2832                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2833                 continue;
2834             }
2835             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2836             if (sceneSession == nullptr) {
2837                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2838                 return WSError::WS_ERROR_INVALID_SESSION;
2839             }
2840             WindowDestroyNotifyVisibility(sceneSession);
2841             dialog->NotifyDestroy();
2842             dialog->Disconnect();
2843 
2844             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2845             if (dialogSceneSession != nullptr) {
2846                 dialogSceneSession->ClearSpecificSessionCbMap();
2847             }
2848             {
2849                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2850                 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2851                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2852                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2853             }
2854         }
2855         sceneSession->ClearDialogVector();
2856         return WSError::WS_OK;
2857     }
2858     return WSError::WS_ERROR_INVALID_SESSION;
2859 }
2860 
DestroySubSession(const sptr<SceneSession> & sceneSession)2861 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2862 {
2863     if (sceneSession == nullptr) {
2864         TLOGW(WmsLogTag::WMS_SUB, "sceneSession is nullptr");
2865         return;
2866     }
2867     for (const auto& subSession : sceneSession->GetSubSession()) {
2868         if (subSession != nullptr) {
2869             const auto persistentId = subSession->GetPersistentId();
2870             TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
2871             DestroyAndDisconnectSpecificSessionInner(persistentId);
2872         }
2873     }
2874 }
2875 
DestroyToastSession(const sptr<SceneSession> & sceneSession)2876 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2877 {
2878     if (sceneSession == nullptr) {
2879         TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2880         return;
2881     }
2882     for (const auto& toastSession : sceneSession->GetToastSession()) {
2883         if (toastSession != nullptr) {
2884             const auto persistentId = toastSession->GetPersistentId();
2885             TLOGI(WmsLogTag::WMS_TOAST, "id: %{public}d", persistentId);
2886             DestroyAndDisconnectSpecificSessionInner(persistentId);
2887         }
2888     }
2889 }
2890 
BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t fingerId,int32_t action,int32_t wid)2891 void SceneSessionManager::BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2892                                                   int32_t fingerId, int32_t action, int32_t wid)
2893 {
2894     if (pointerEvent == nullptr) {
2895         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null, wid:%{public}d fingerId:%{public}d action:%{public}d",
2896                   wid, fingerId, action);
2897         return;
2898     }
2899     pointerEvent->SetId(CANCEL_POINTER_ID);
2900     pointerEvent->SetTargetWindowId(wid);
2901     pointerEvent->SetPointerId(fingerId);
2902     pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
2903     MMI::PointerEvent::PointerItem item;
2904     item.SetPointerId(fingerId);
2905     pointerEvent->AddPointerItem(item);
2906     if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
2907         pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
2908     } else {
2909         pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
2910     }
2911 }
2912 
SendCancelEventBeforeEraseSession(const sptr<SceneSession> & sceneSession)2913 void SceneSessionManager::SendCancelEventBeforeEraseSession(const sptr<SceneSession>& sceneSession)
2914 {
2915     auto task = [this, needCancelEventSceneSession = sceneSession] {
2916         if (needCancelEventSceneSession == nullptr) {
2917             TLOGI(WmsLogTag::WMS_EVENT, "scenesession is nullptr, needn't send cancel event");
2918             return;
2919         }
2920         auto wid = needCancelEventSceneSession->GetPersistentId();
2921         if (needCancelEventSceneSession->GetMousePointerDownEventStatus()) {
2922             std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2923             BuildCancelPointerEvent(pointerEvent, 1, MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN, wid);
2924             TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send mouse cancel. wid:%{public}d", wid);
2925             needCancelEventSceneSession->SetMousePointerDownEventStatus(false);
2926             needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2927         }
2928         std::unordered_set<int32_t> fingerPointerDownStatusList = needCancelEventSceneSession->GetFingerPointerDownStatusList();
2929         if (fingerPointerDownStatusList.empty()) {
2930             return;
2931         }
2932         for (auto fingerId : fingerPointerDownStatusList) {
2933             std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2934             BuildCancelPointerEvent(pointerEvent, fingerId, MMI::PointerEvent::POINTER_ACTION_DOWN, wid);
2935             TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send touch cancel. wid:%{public}d fingerId:%{public}d",
2936                   wid, fingerId);
2937             needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2938             needCancelEventSceneSession->RemoveFingerPointerDownStatus(fingerId);
2939         }
2940     };
2941     mainHandler_->PostTask(std::move(task), "wms:sendCancelBeforeEraseSession", 0, AppExecFwk::EventQueue::Priority::VIP);
2942 }
2943 
EraseSceneSessionMapById(int32_t persistentId)2944 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2945 {
2946     auto sceneSession = GetSceneSession(persistentId);
2947     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2948     EraseSceneSessionAndMarkDirtyLocked(persistentId);
2949     systemTopSceneSessionMap_.erase(persistentId);
2950     nonSystemFloatSceneSessionMap_.erase(persistentId);
2951     SendCancelEventBeforeEraseSession(sceneSession);
2952     if (sceneSession && MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2953         MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2954         MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
2955     }
2956 }
2957 
2958 /**
2959  * if visible session is erased, mark dirty
2960  * lock-free
2961  */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2962 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2963 {
2964     // get scene session lock-free
2965     auto iter = sceneSessionMap_.find(persistentId);
2966     if (iter == sceneSessionMap_.end()) {
2967         TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2968         return;
2969     }
2970     const auto& sceneSession = iter->second;
2971     if (sceneSession != nullptr && sceneSession->IsVisible()) {
2972         sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2973     }
2974     sceneSessionMap_.erase(persistentId);
2975 }
2976 
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean,bool isUserRequestedExit)2977 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2978     bool needRemoveSession, bool isSaveSnapshot, bool isForceClean, bool isUserRequestedExit)
2979 {
2980     auto task = [this, weakSceneSession = wptr(sceneSession), needRemoveSession, isSaveSnapshot, isForceClean,
2981                  isUserRequestedExit]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
2982         auto sceneSession = weakSceneSession.promote();
2983         if (sceneSession == nullptr) {
2984             TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2985             return WSError::WS_ERROR_NULLPTR;
2986         }
2987         auto persistentId = sceneSession->GetPersistentId();
2988         TLOGNI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d "
2989             "isForceClean:%{public}d isUserRequestedExit:%{public}d", persistentId, needRemoveSession, isSaveSnapshot,
2990             isForceClean, isUserRequestedExit);
2991         RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2992         avoidAreaListenerSessionSet_.erase(persistentId);
2993         DestroyDialogWithMainWindow(sceneSession);
2994         DestroyToastSession(sceneSession);
2995         DestroySubSession(sceneSession); // destroy sub session by destruction
2996         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2997         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2998             WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sceneSession->GetSessionInfo().bundleName_);
2999         }
3000         WindowDestroyNotifyVisibility(sceneSession);
3001         NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
3002         sceneSession->SetRemoveSnapshotCallback([this, persistentId]() {
3003             this->RemoveSnapshotFromCache(persistentId);
3004         });
3005         if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) {
3006             TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId);
3007             if (!sceneSession->UpdateInteractiveInner(false)) {
3008                 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId);
3009             }
3010         }
3011         sceneSession->DisconnectTask(false, isSaveSnapshot);
3012         if (!GetSceneSession(persistentId)) {
3013             TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
3014             return WSError::WS_ERROR_INVALID_SESSION;
3015         }
3016         auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
3017         sceneSession->GetCloseAbilityWantAndClean(sceneSessionInfo->want);
3018         ResetSceneSessionInfoWant(sceneSessionInfo);
3019         return RequestSceneSessionDestructionInner(
3020             sceneSession, sceneSessionInfo, needRemoveSession, isForceClean, isUserRequestedExit);
3021     };
3022     std::string taskName = "RequestSceneSessionDestruction:PID:" +
3023         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
3024     taskScheduler_->PostAsyncTask(task, taskName);
3025     return WSError::WS_OK;
3026 }
3027 
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)3028 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
3029 {
3030     if (sceneSessionInfo->resultCode == -1) {
3031         AAFwk::Want want;
3032         std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3033         want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3034         sceneSessionInfo->want = std::move(want);
3035         TLOGI(WmsLogTag::WMS_MAIN, "keySessionId: %{public}s", keySessionId.c_str());
3036     }
3037 }
3038 
ResetWantInfo(const sptr<SceneSession> & sceneSession)3039 void SceneSessionManager::ResetWantInfo(const sptr<SceneSession>& sceneSession)
3040 {
3041     if (const auto sessionInfoWant = sceneSession->GetSessionInfo().want) {
3042         const auto& bundleName = sessionInfoWant->GetElement().GetBundleName();
3043         const auto& abilityName = sessionInfoWant->GetElement().GetAbilityName();
3044         const auto& keySessionId = sessionInfoWant->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3045         AppExecFwk::ElementName element;
3046         element.SetBundleName(bundleName);
3047         element.SetAbilityName(abilityName);
3048         auto want = std::make_shared<AAFwk::Want>();
3049         want->SetElement(element);
3050         want->SetBundle(bundleName);
3051         if (!keySessionId.empty()) {
3052             want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3053         }
3054         sceneSession->SetSessionInfoWant(want);
3055     }
3056 }
3057 
RequestSceneSessionDestructionInner(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> sceneSessionInfo,const bool needRemoveSession,const bool isForceClean,bool isUserRequestedExit)3058 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession,
3059     sptr<AAFwk::SessionInfo> sceneSessionInfo, const bool needRemoveSession, const bool isForceClean,
3060     bool isUserRequestedExit)
3061 {
3062     auto persistentId = sceneSession->GetPersistentId();
3063     TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}d",
3064         persistentId, sceneSession->GetSessionInfo().isSystem_);
3065     if (isForceClean) {
3066         AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit,
3067             static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3068     } else {
3069         AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit,
3070             static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3071     }
3072     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
3073     if (needRemoveSession) {
3074         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3075             NotifyClearSession(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
3076         }
3077         EraseSceneSessionMapById(persistentId);
3078     } else {
3079         // if terminate, reset want. so start from recent, start a new one.
3080         TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
3081         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3082             sceneSession->SetSessionInfoWant(nullptr);
3083         }
3084         ResetWantInfo(sceneSession);
3085         sceneSession->ResetSessionInfoResultCode();
3086     }
3087     NotifySessionForCallback(sceneSession, needRemoveSession);
3088     // Clear js cb map if needed.
3089     sceneSession->ClearJsSceneSessionCbMap(needRemoveSession);
3090     return WSError::WS_OK;
3091 }
3092 
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)3093 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
3094     const sptr<SceneSession>& sceneSession)
3095 {
3096     if (sceneSession == nullptr || sessionStage == nullptr) {
3097         TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
3098         return;
3099     }
3100 
3101     auto remoteObject = sessionStage->AsObject();
3102     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
3103     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
3104         TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
3105         return;
3106     }
3107     TLOGD(WmsLogTag::WMS_LIFE, "Id: %{public}d", sceneSession->GetPersistentId());
3108 }
3109 
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)3110 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
3111 {
3112     taskScheduler_->PostAsyncTask([this, remoteObject] {
3113         auto iter = remoteObjectMap_.find(remoteObject);
3114         if (iter == remoteObjectMap_.end()) {
3115             TLOGNE(WmsLogTag::WMS_DIALOG, "Invalid remoteObject");
3116             return;
3117         }
3118         TLOGND(WmsLogTag::WMS_DIALOG, "Remote died, id: %{public}d", iter->second);
3119         auto sceneSession = GetSceneSession(iter->second);
3120         if (sceneSession == nullptr) {
3121             TLOGNW(WmsLogTag::WMS_DIALOG, "Remote died, session is nullptr, id: %{public}d", iter->second);
3122             return;
3123         }
3124         DestroyAndDisconnectSpecificSessionInner(iter->second);
3125     }, __func__);
3126 }
3127 
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)3128 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3129     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3130     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
3131     SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
3132 {
3133     if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
3134         TLOGE(WmsLogTag::WMS_LIFE, "create system window or modal subwindow permission denied!");
3135         return WSError::WS_ERROR_NOT_SYSTEM_APP;
3136     }
3137     auto parentSession = GetSceneSession(property->GetParentPersistentId());
3138     if (parentSession) {
3139         auto parentProperty = parentSession->GetSessionProperty();
3140         if (parentProperty->GetSubWindowLevel() >= MAX_SUB_WINDOW_LEVEL) {
3141             TLOGE(WmsLogTag::WMS_SUB, "sub window level exceeds limit");
3142             return WSError::WS_ERROR_INVALID_WINDOW;
3143         }
3144         property->SetSubWindowLevel(parentProperty->GetSubWindowLevel() + 1);
3145     }
3146     auto initClientDisplayId = UpdateSpecificSessionClientDisplayId(property);
3147     TLOGI(WmsLogTag::WMS_LIFE, "The corner radius is %{public}f", appWindowSceneConfig_.floatCornerRadius_);
3148     property->SetWindowCornerRadius(appWindowSceneConfig_.floatCornerRadius_);
3149     bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
3150                         property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
3151     bool isSystemCalling = SessionPermission::IsSystemCalling();
3152     if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
3153         if (parentSession) {
3154             shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
3155         }
3156     }
3157     if (systemConfig_.IsPcWindow() && property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
3158         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't block");
3159         shouldBlock = false;
3160     }
3161     if (shouldBlock) {
3162         TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
3163         return WSError::WS_ERROR_INVALID_OPERATION;
3164     }
3165 
3166     if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
3167         WSError err = CheckSubSessionStartedByExtensionAndSetDisplayId(token, property, sessionStage);
3168         if (err != WSError::WS_OK) {
3169             return err;
3170         }
3171     }
3172     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
3173     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
3174         TLOGE(WmsLogTag::DEFAULT, "The alarm window has been deprecated!");
3175         return WSError::WS_ERROR_INVALID_WINDOW;
3176     }
3177 
3178     TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
3179         property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
3180 
3181     // Get pid and uid before posting task.
3182     auto pid = IPCSkeleton::GetCallingRealPid();
3183     auto uid = IPCSkeleton::GetCallingUid();
3184     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &persistentId, &session, &systemConfig, token,
3185                  pid, uid, isSystemCalling, initClientDisplayId]() {
3186         if (property == nullptr) {
3187             TLOGNE(WmsLogTag::WMS_LIFE, "property is nullptr");
3188             return WSError::WS_ERROR_NULLPTR;
3189         }
3190         if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !IsEnablePiPCreate(property)) {
3191             TLOGNE(WmsLogTag::WMS_PIP, "pip window is not enable to create.");
3192             return WSError::WS_DO_NOTHING;
3193         }
3194         const auto type = property->GetWindowType();
3195         // create specific session
3196         SessionInfo info;
3197         info.windowType_ = static_cast<uint32_t>(type);
3198         info.bundleName_ = property->GetSessionInfo().bundleName_;
3199         info.abilityName_ = property->GetSessionInfo().abilityName_;
3200         info.moduleName_ = property->GetSessionInfo().moduleName_;
3201         info.screenId_ = property->GetDisplayId();
3202 
3203         if (IsPiPForbidden(property, type)) {
3204             TLOGNE(WmsLogTag::WMS_PIP, "forbid pip");
3205             return WSError::WS_ERROR_INVALID_PERMISSION;
3206         }
3207         ClosePipWindowIfExist(type);
3208         sptr<SceneSession> newSession = RequestSceneSession(info, property);
3209         if (newSession == nullptr) {
3210             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
3211             return WSError::WS_ERROR_NULLPTR;
3212         }
3213         newSession->SetClientDisplayId(initClientDisplayId);
3214         newSession->GetSessionProperty()->SetWindowCornerRadius(property->GetWindowCornerRadius());
3215         property->SetSystemCalling(isSystemCalling);
3216         auto errCode = newSession->ConnectInner(
3217             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
3218         newSession->SetIsSystemSpecificSession(isSystemCalling);
3219         systemConfig = systemConfig_;
3220         persistentId = property->GetPersistentId();
3221 
3222         NotifyCreateSpecificSession(newSession, property, type);
3223         session = newSession;
3224         AddClientDeathRecipient(sessionStage, newSession);
3225 
3226         if (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
3227             CheckFloatWindowIsAnco(pid, newSession);
3228         }
3229 
3230         TLOGNI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
3231             "parentId: %{public}d, type: %{public}d",
3232             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
3233         return errCode;
3234     };
3235 
3236     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
3237 }
3238 
CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject> & token,const sptr<WindowSessionProperty> & property,const sptr<ISessionStage> & sessionStage)3239 WSError SceneSessionManager::CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject>& token,
3240     const sptr<WindowSessionProperty>& property, const sptr<ISessionStage>& sessionStage)
3241 {
3242     sptr<SceneSession> extensionParentSession = GetSceneSession(property->GetParentPersistentId());
3243     if (extensionParentSession == nullptr) {
3244         TLOGE(WmsLogTag::WMS_UIEXT, "extensionParentSession is invalid with %{public}d",
3245             property->GetParentPersistentId());
3246         return WSError::WS_ERROR_NULLPTR;
3247     }
3248     auto pid = IPCSkeleton::GetCallingRealPid();
3249     auto parentPid = extensionParentSession->GetCallingPid();
3250     WSError result = WSError::WS_ERROR_INVALID_WINDOW;
3251     if (pid == parentPid) { // Determine Whether to create a sub window in the same process.
3252         TLOGI(WmsLogTag::WMS_UIEXT, "pid == parentPid");
3253         result = WSError::WS_OK;
3254     }
3255     AAFwk::UIExtensionSessionInfo info;
3256     AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
3257     if (info.persistentId != INVALID_SESSION_ID && info.hostWindowId != INVALID_SESSION_ID) {
3258         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
3259         // Check the parent ids are the same in cross-process scenarios.
3260         if (parentId == property->GetParentPersistentId()) {
3261             TLOGI(WmsLogTag::WMS_UIEXT, "parentId == property->GetParentPersistentId(parentId:%{public}d)", parentId);
3262             result = WSError::WS_OK;
3263         }
3264     }
3265     if (SessionPermission::IsSystemCalling()) { // Fallback strategy.
3266         TLOGI(WmsLogTag::WMS_UIEXT, "is system app");
3267         result = WSError::WS_OK;
3268     }
3269     if (property->GetIsUIExtensionAbilityProcess() && SessionPermission::IsStartedByUIExtension()) {
3270         AAFwk::UIExtensionHostInfo hostInfo;
3271         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
3272         const auto& sessionInfo = extensionParentSession->GetSessionInfo();
3273         if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
3274             TLOGE(WmsLogTag::WMS_UIEXT, "The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s,"
3275                 " hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
3276                 hostInfo.elementName_.GetBundleName().c_str());
3277             ReportSubWindowCreationFailure(pid, info.elementName.GetAbilityName(), sessionInfo.bundleName_,
3278                 hostInfo.elementName_.GetBundleName());
3279             return WSError::WS_ERROR_INVALID_WINDOW;
3280         }
3281         result = WSError::WS_OK;
3282     }
3283     if (result == WSError::WS_OK) {
3284         sptr<WindowSessionProperty> parentProperty = extensionParentSession->GetSessionProperty();
3285         if (sessionStage && property->GetIsUIExtFirstSubWindow()) {
3286             sessionStage->UpdateDisplayId(parentProperty->GetDisplayId());
3287             property->SetDisplayId(parentProperty->GetDisplayId());
3288         }
3289     } else {
3290         TLOGE(WmsLogTag::WMS_UIEXT, "can't create sub window: persistentId %{public}d", property->GetPersistentId());
3291     }
3292     return result;
3293 }
3294 
ReportSubWindowCreationFailure(int32_t pid,const std::string & abilityName,const std::string & parentBundleName,const std::string & hostBundleName)3295 void SceneSessionManager::ReportSubWindowCreationFailure(int32_t pid, const std::string& abilityName,
3296         const std::string& parentBundleName, const std::string& hostBundleName)
3297 {
3298     taskScheduler_->PostAsyncTask([pid, abilityName, parentBundleName, hostBundleName]() {
3299         std::ostringstream oss;
3300         oss << "The hostWindow is not this parentwindow ! parentwindow bundleName: " << parentBundleName;
3301         oss << ", hostwindow bundleName: " << hostBundleName;
3302         oss << ", abilityName: " << abilityName;
3303         SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(
3304             static_cast<int32_t>(WindowDFXHelperType::WINDOW_CREATE_SUB_WINDOW_FAILED), pid, oss.str());
3305     }, __func__);
3306 }
3307 
CheckFloatWindowIsAnco(pid_t pid,const sptr<SceneSession> & newSession)3308 void SceneSessionManager::CheckFloatWindowIsAnco(pid_t pid, const sptr<SceneSession>& newSession)
3309 {
3310     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
3311     {
3312         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3313         sceneSessionMapCopy = sceneSessionMap_;
3314     }
3315     for (const auto& [_, session] : sceneSessionMapCopy) {
3316         if (session && session->GetCallingPid() == pid &&
3317             session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3318             auto sessionInfo = session->GetSessionInfo();
3319             if (AbilityInfoManager::GetInstance().IsAnco(sessionInfo.bundleName_,
3320                     sessionInfo.abilityName_, sessionInfo.moduleName_)) {
3321                 newSession->SetIsAncoForFloatingWindow(true);
3322                 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set float window is anco, wid: %{public}d", newSession->GetWindowId());
3323                 break;
3324             }
3325         }
3326     }
3327 }
3328 
ClosePipWindowIfExist(WindowType type)3329 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
3330 {
3331     if (type != WindowType::WINDOW_TYPE_PIP) {
3332         return;
3333     }
3334     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3335     for (const auto& [_, session] : sceneSessionMap_) {
3336         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
3337             session->NotifyCloseExistPipWindow();
3338             break;
3339         }
3340     }
3341 }
3342 
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)3343 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
3344 {
3345     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3346     for (const auto& [_, session] : sceneSessionMap_) {
3347         if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
3348             pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
3349             session->IsSessionForeground()) {
3350             if (startPiPFailedFunc_) {
3351                 startPiPFailedFunc_();
3352             }
3353             TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
3354             return false;
3355         }
3356     }
3357     return true;
3358 }
3359 
IsEnablePiPCreate(const sptr<WindowSessionProperty> & property)3360 bool SceneSessionManager::IsEnablePiPCreate(const sptr<WindowSessionProperty>& property)
3361 {
3362     if (isScreenLocked_) {
3363         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
3364         return false;
3365     }
3366     Rect pipRect = property->GetRequestRect();
3367     if (pipRect.width_ == 0 || pipRect.height_ == 0) {
3368         TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
3369         return false;
3370     }
3371     if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
3372         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
3373         return false;
3374     }
3375     auto parentSession = GetSceneSession(property->GetParentPersistentId());
3376     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
3377         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
3378         return false;
3379     }
3380     return true;
3381 }
3382 
IsPiPForbidden(const sptr<WindowSessionProperty> & property,const WindowType & type)3383 bool SceneSessionManager::IsPiPForbidden(const sptr<WindowSessionProperty>& property, const WindowType& type)
3384 {
3385     sptr<SceneSession> parentSession = GetSceneSession(property->GetParentPersistentId());
3386     if (parentSession == nullptr) {
3387         TLOGE(WmsLogTag::WMS_PIP, "invalid parentSession");
3388         return false;
3389     }
3390     sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
3391     if (parentProperty == nullptr) {
3392         TLOGE(WmsLogTag::WMS_PIP, "invalid parentProperty");
3393         return false;
3394     }
3395     DisplayId screenId = parentProperty->GetDisplayId();
3396     if (screenId == SCREEN_ID_INVALID) {
3397         TLOGE(WmsLogTag::WMS_PIP, "invalid screenId");
3398         return false;
3399     }
3400     sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(screenId);
3401     if (screenSession == nullptr) {
3402         TLOGE(WmsLogTag::WMS_PIP, "invalid screenSession");
3403         return false;
3404     }
3405     std::string screenName = screenSession->GetName();
3406     if (type == WindowType::WINDOW_TYPE_PIP &&
3407        (screenName == "HiCar" || screenName == "SuperLauncher")) {
3408         TLOGI(WmsLogTag::WMS_PIP, "screen name %{public}s", screenName.c_str());
3409         return true;
3410     }
3411     return false;
3412 }
3413 
NotifyPiPWindowVisibleChange(bool screenLocked)3414 void SceneSessionManager::NotifyPiPWindowVisibleChange(bool screenLocked) {
3415     sptr<SceneSession> session = SelectSesssionFromMap(pipWindowSurfaceId_);
3416     if (session != nullptr) {
3417         std::vector<std::pair<uint64_t, WindowVisibilityState>> pipVisibilityChangeInfos;
3418         if (screenLocked) {
3419             pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
3420         } else {
3421             pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_NO_OCCLUSION);
3422         }
3423         DealwithVisibilityChange(pipVisibilityChangeInfos, lastVisibleData_);
3424     }
3425 }
3426 
IsLastPiPWindowVisible(uint64_t surfaceId,WindowVisibilityState lastVisibilityState)3427 bool SceneSessionManager::IsLastPiPWindowVisible(uint64_t surfaceId, WindowVisibilityState lastVisibilityState) {
3428     sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
3429     if (session == nullptr || session->GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
3430         TLOGD(WmsLogTag::WMS_PIP, "session is null or windowMode is not PIP");
3431         return false;
3432     }
3433     if (isScreenLocked_) {
3434         TLOGD(WmsLogTag::WMS_PIP, "pipWindow occlusion because of screen locked");
3435         return false;
3436     }
3437     if (lastVisibilityState != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
3438         // no visibility notification processing after pip is occlusion
3439         TLOGI(WmsLogTag::WMS_PIP, "pipWindow occlusion success. pipWindowSurfaceId: %{public}" PRIu64, surfaceId);
3440         pipWindowSurfaceId_ = surfaceId;
3441         return true;
3442     }
3443     return false;
3444 }
3445 
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)3446 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
3447 {
3448     WindowType type = property->GetWindowType();
3449     if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
3450         return true;
3451     }
3452 
3453     if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
3454         TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
3455         return false;
3456     }
3457 
3458     if (!SessionPermission::IsSystemCalling()) {
3459         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
3460         return false;
3461     }
3462 
3463     return true;
3464 }
3465 
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)3466 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
3467 {
3468     WindowType type = property->GetWindowType();
3469     if (WindowHelper::IsUIExtensionWindow(type)) {
3470         // UIExtension window disallowed.
3471         return false;
3472     }
3473     if (!WindowHelper::IsSystemWindow(type)) {
3474         // type is not system
3475         return true;
3476     }
3477     if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && property->IsSystemKeyboard()) {
3478         // system keyboard window can only be created by virtual keyboard service
3479         if (SessionPermission::VerifyCallingPermission("ohos.permission.VIRTUAL_KEYBOARD_WINDOW")) {
3480             TLOGD(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check sucess.");
3481             return true;
3482         }
3483         TLOGE(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check failed.");
3484         return false;
3485     }
3486     if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
3487          type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) && SessionPermission::IsStartedByInputMethod()) {
3488         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
3489         TLOGD(WmsLogTag::WMS_KEYBOARD, "check create permission success, input method app create input method window.");
3490         return true;
3491     }
3492     if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
3493         // some system types could be created by normal app
3494         return true;
3495     }
3496     if (type == WindowType::WINDOW_TYPE_FLOAT) {
3497         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
3498         if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
3499             (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd() ||
3500             systemConfig_.supportTypeFloatWindow_)) {
3501             TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission success.");
3502             return true;
3503         } else {
3504             TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission failed.");
3505             return false;
3506         }
3507     }
3508     if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
3509         int32_t parentId = property->GetParentPersistentId();
3510         auto parentSession = GetSceneSession(parentId);
3511         if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
3512             SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
3513             TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
3514             return true;
3515         } else {
3516             TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
3517         }
3518     }
3519     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
3520         TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
3521         return true;
3522     }
3523     TLOGE(WmsLogTag::WMS_SYSTEM, "finally check permission failed.");
3524     return false;
3525 }
3526 
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)3527 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
3528 {
3529     if (property == nullptr) {
3530         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3531         return {};
3532     }
3533     SessionInfo sessionInfo = property->GetSessionInfo();
3534     sessionInfo.persistentId_ = property->GetPersistentId();
3535     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
3536     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
3537     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
3538     sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
3539                                     ? SessionState::STATE_ACTIVE
3540                                     : SessionState::STATE_BACKGROUND;
3541     sessionInfo.isPersistentRecover_ = true;
3542     sessionInfo.appInstanceKey_ = property->GetAppInstanceKey();
3543     TLOGI(WmsLogTag::WMS_RECOVER,
3544         "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
3545         "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
3546         "windowState=%{public}u, appInstanceKey=%{public}s",
3547         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
3548         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_,
3549         sessionInfo.appInstanceKey_.c_str());
3550     return sessionInfo;
3551 }
3552 
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)3553 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
3554 {
3555     TLOGI(WmsLogTag::WMS_RECOVER, "Size of PersistentIds need to be recovered=%{public}zu, CurrentUserId=%{public}d",
3556         alivePersistentIds.size(), currentUserId_.load());
3557     alivePersistentIds_ = alivePersistentIds;
3558 }
3559 
IsNeedRecover(const int32_t persistentId)3560 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
3561 {
3562     if (auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
3563         it == alivePersistentIds_.end()) {
3564         TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
3565         return false;
3566     }
3567     return true;
3568 }
3569 
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)3570 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
3571     bool isSpecificSession)
3572 {
3573     if (property == nullptr) {
3574         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3575         return WSError::WS_ERROR_NULLPTR;
3576     }
3577     if (!CheckSystemWindowPermission(property)) {
3578         TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
3579         return WSError::WS_ERROR_NOT_SYSTEM_APP;
3580     }
3581     if (isSpecificSession) {
3582         if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
3583             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
3584             return WSError::WS_ERROR_INVALID_PARAM;
3585         }
3586     } else {
3587         if (property->GetPersistentId() > 0 && !IsNeedRecover(property->GetPersistentId())) {
3588             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
3589             return WSError::WS_ERROR_INVALID_PARAM;
3590         }
3591     }
3592     return WSError::WS_OK;
3593 }
3594 
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)3595 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3596     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3597     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
3598 {
3599     auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
3600     if (propCheckRet != WSError::WS_OK) {
3601         return propCheckRet;
3602     }
3603     auto pid = IPCSkeleton::GetCallingRealPid();
3604     auto uid = IPCSkeleton::GetCallingUid();
3605     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
3606         if (recoveringFinished_) {
3607             TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3608             return WSError::WS_ERROR_INVALID_OPERATION;
3609         }
3610         UpdateRecoverPropertyForSuperFold(property);
3611         // recover specific session
3612         SessionInfo info = RecoverSessionInfo(property);
3613         TLOGNI(WmsLogTag::WMS_RECOVER, "callingWindowId=%{public}" PRIu32, property->GetCallingSessionId());
3614         ClosePipWindowIfExist(property->GetWindowType());
3615         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
3616         if (sceneSession == nullptr) {
3617             TLOGNE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
3618             return WSError::WS_ERROR_NULLPTR;
3619         }
3620 
3621         auto persistentId = sceneSession->GetPersistentId();
3622         if (persistentId != info.persistentId_) {
3623             TLOGNE(WmsLogTag::WMS_RECOVER,
3624                 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
3625                 info.persistentId_, persistentId, property->GetParentPersistentId());
3626             failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
3627             EraseSceneSessionMapById(persistentId);
3628             return WSError::WS_ERROR_INVALID_SESSION;
3629         }
3630 
3631         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3632         if (errCode != WSError::WS_OK) {
3633             TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
3634             EraseSceneSessionMapById(persistentId);
3635             return errCode;
3636         }
3637         NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
3638         CacheSpecificSessionForRecovering(sceneSession, property);
3639         NotifySessionUnfocusedToClient(persistentId);
3640         AddClientDeathRecipient(sessionStage, sceneSession);
3641         session = sceneSession;
3642         return errCode;
3643     };
3644     return taskScheduler_->PostSyncTask(task, __func__);
3645 }
3646 
NotifyRecoveringFinished()3647 void SceneSessionManager::NotifyRecoveringFinished()
3648 {
3649     taskScheduler_->PostAsyncTask([this]() {
3650         TLOGNI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
3651         recoveringFinished_ = true;
3652         recoverSubSessionCacheMap_.clear();
3653         recoverDialogSessionCacheMap_.clear();
3654     }, __func__);
3655 }
3656 
CacheSpecificSessionForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)3657 void SceneSessionManager::CacheSpecificSessionForRecovering(
3658     const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
3659 {
3660     if (!IsWindowSupportCacheForRecovering(sceneSession, property)) {
3661         return;
3662     }
3663 
3664     auto windowType = property->GetWindowType();
3665     auto parentId = property->GetParentPersistentId();
3666     TLOGI(WmsLogTag::WMS_RECOVER, "Cache specific session persistentId=%{public}d, parent persistentId="
3667         "%{public}d, window type=%{public}d", sceneSession->GetPersistentId(), parentId, windowType);
3668 
3669     if (WindowHelper::IsSubWindow(windowType)) {
3670         recoverSubSessionCacheMap_[parentId].emplace_back(sceneSession);
3671     } else if (WindowHelper::IsDialogWindow(windowType)) {
3672         recoverDialogSessionCacheMap_[parentId].emplace_back(sceneSession);
3673     }
3674 }
3675 
IsWindowSupportCacheForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)3676 bool SceneSessionManager::IsWindowSupportCacheForRecovering(
3677     const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
3678 {
3679     if (recoveringFinished_) {
3680         TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
3681         return false;
3682     }
3683 
3684     if (sceneSession == nullptr || property == nullptr) {
3685         TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
3686         return false;
3687     }
3688 
3689     auto windowType = property->GetWindowType();
3690     if (!WindowHelper::IsSubWindow(windowType) && !WindowHelper::IsDialogWindow(windowType)) {
3691         return false;
3692     }
3693 
3694     auto parentId = property->GetParentPersistentId();
3695     if ((WindowHelper::IsSubWindow(windowType) &&
3696          createSubSessionFuncMap_.find(parentId) != createSubSessionFuncMap_.end()) ||
3697         (WindowHelper::IsDialogWindow(windowType) &&
3698          bindDialogTargetFuncMap_.find(parentId) != bindDialogTargetFuncMap_.end())) {
3699         return false;
3700     }
3701 
3702     return true;
3703 }
3704 
RecoverCachedSubSession(int32_t persistentId)3705 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
3706 {
3707     auto iter = recoverSubSessionCacheMap_.find(persistentId);
3708     if (iter == recoverSubSessionCacheMap_.end()) {
3709         return;
3710     }
3711     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
3712     for (auto& sceneSession : iter->second) {
3713         NotifyCreateSubSession(persistentId, sceneSession);
3714     }
3715     recoverSubSessionCacheMap_.erase(iter);
3716 }
3717 
RecoverCachedDialogSession(int32_t persistentId)3718 void SceneSessionManager::RecoverCachedDialogSession(int32_t persistentId)
3719 {
3720     auto iter = recoverDialogSessionCacheMap_.find(persistentId);
3721     if (iter == recoverDialogSessionCacheMap_.end()) {
3722         return;
3723     }
3724     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
3725     for (auto& sceneSession : iter->second) {
3726         UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
3727     }
3728     recoverDialogSessionCacheMap_.erase(iter);
3729 }
3730 
NotifySessionUnfocusedToClient(int32_t persistentId)3731 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
3732 {
3733     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
3734     listenerController_->NotifySessionUnfocused(persistentId);
3735 }
3736 
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)3737 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
3738     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3739     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
3740 {
3741     auto result = CheckSessionPropertyOnRecovery(property, false);
3742     if (result != WSError::WS_OK) {
3743         return result;
3744     }
3745     auto pid = IPCSkeleton::GetCallingRealPid();
3746     auto uid = IPCSkeleton::GetCallingUid();
3747     auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
3748         if (recoveringFinished_) {
3749             TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3750             return WSError::WS_ERROR_INVALID_OPERATION;
3751         }
3752         if (recoverSceneSessionFunc_ == nullptr) {
3753             TLOGNE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
3754             return WSError::WS_ERROR_NULLPTR;
3755         }
3756         UpdateRecoverPropertyForSuperFold(property);
3757         SessionInfo sessionInfo = RecoverSessionInfo(property);
3758         sptr<SceneSession> sceneSession = RequestSceneSession(sessionInfo, nullptr);
3759         if (sceneSession == nullptr) {
3760             TLOGNE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
3761             return WSError::WS_ERROR_NULLPTR;
3762         }
3763         int32_t persistentId = sceneSession->GetPersistentId();
3764         if (persistentId != sessionInfo.persistentId_) {
3765             TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
3766                 sessionInfo.persistentId_, persistentId);
3767             EraseSceneSessionMapById(persistentId);
3768             return WSError::WS_ERROR_INVALID_SESSION;
3769         }
3770         auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3771         if (ret != WSError::WS_OK) {
3772             TLOGNE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
3773             EraseSceneSessionMapById(sessionInfo.persistentId_);
3774             return ret;
3775         }
3776         sceneSession->SetRecovered(true);
3777         recoverSceneSessionFunc_(sceneSession, sessionInfo);
3778         NotifySessionUnfocusedToClient(persistentId);
3779         session = sceneSession;
3780         return WSError::WS_OK;
3781     };
3782     return taskScheduler_->PostSyncTask(task, __func__);
3783 }
3784 
UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty> & property)3785 void SceneSessionManager::UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty>& property)
3786 {
3787     if (property->GetDisplayId() != VIRTUAL_DISPLAY_ID) {
3788         return;
3789     }
3790     static auto foldCreaseRegion = SingletonContainer::Get<DisplayManager>().GetCurrentFoldCreaseRegion();
3791     if (foldCreaseRegion == nullptr) {
3792         return;
3793     }
3794     Rect recoverWindowRect = property->GetWindowRect();
3795     Rect recoverRequestRect = property->GetRequestRect();
3796     TLOGD(WmsLogTag::WMS_RECOVER,
3797         "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
3798         recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
3799         static_cast<uint32_t>(property->GetDisplayId()));
3800 
3801     auto foldCrease = foldCreaseRegion->GetCreaseRects().front();
3802     recoverWindowRect.posY_ += foldCrease.posY_ + foldCrease.height_;
3803     recoverRequestRect.posY_ += foldCrease.posY_ + foldCrease.height_;
3804     property->SetWindowRect(recoverWindowRect);
3805     property->SetRequestRect(recoverRequestRect);
3806     property->SetDisplayId(0);
3807     TLOGD(WmsLogTag::WMS_RECOVER,
3808         "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
3809         recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
3810         static_cast<uint32_t>(property->GetDisplayId()));
3811 }
3812 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)3813 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
3814 {
3815     TLOGI(WmsLogTag::WMS_RECOVER, "in");
3816     recoverSceneSessionFunc_ = func;
3817 }
3818 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)3819 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
3820 {
3821     createSystemSessionFunc_ = func;
3822 }
3823 
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)3824 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
3825 {
3826     createKeyboardSessionFunc_ = func;
3827 }
3828 
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)3829 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
3830 {
3831     startPiPFailedFunc_ = std::move(func);
3832 }
3833 
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)3834 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
3835     const NotifyCreateSubSessionFunc& func)
3836 {
3837     TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
3838     taskScheduler_->PostSyncTask([this, persistentId, func]() {
3839         createSubSessionFuncMap_[persistentId] = func;
3840         RecoverCachedSubSession(persistentId);
3841         return WMError::WM_OK;
3842     }, __func__);
3843 }
3844 
RegisterBindDialogTargetListener(const sptr<SceneSession> & session,NotifyBindDialogSessionFunc && func)3845 void SceneSessionManager::RegisterBindDialogTargetListener(const sptr<SceneSession>& session,
3846     NotifyBindDialogSessionFunc&& func)
3847 {
3848     int32_t persistentId = session->GetPersistentId();
3849     TLOGI(WmsLogTag::WMS_DIALOG, "Id: %{public}d", persistentId);
3850     taskScheduler_->PostTask([this, session, persistentId, func = std::move(func)] {
3851         session->RegisterBindDialogSessionCallback(func);
3852         bindDialogTargetFuncMap_[persistentId] = std::move(func);
3853         RecoverCachedDialogSession(persistentId);
3854     }, __func__);
3855 }
3856 
SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession> & newSession)3857 void SceneSessionManager::SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession>& newSession)
3858 {
3859     if (newSession->GetSessionProperty()->GetDisplayId() == DISPLAY_ID_INVALID) {
3860         uint64_t defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
3861         int32_t focusSessionId = windowFocusController_->GetFocusedSessionId(defaultDisplayId);
3862         auto focusedSession = GetSceneSession(focusSessionId);
3863         DisplayId displayId = defaultDisplayId;
3864         if (focusedSession != nullptr && focusedSession->GetSessionProperty()->GetDisplayId() != DISPLAY_ID_INVALID) {
3865             displayId = focusedSession->GetSessionProperty()->GetDisplayId();
3866             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, focus id %{public}d, display id: %{public}" PRIu64,
3867                 newSession->GetPersistentId(), focusedSession->GetPersistentId(), displayId);
3868         } else {
3869             TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get focus id failed, use default displayId %{public}" PRIu64, displayId);
3870         }
3871         newSession->SetScreenId(displayId);
3872         newSession->GetSessionProperty()->SetDisplayId(displayId);
3873     }
3874 }
3875 
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)3876 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
3877     sptr<WindowSessionProperty> property, const WindowType& type)
3878 {
3879     if (newSession == nullptr || property == nullptr) {
3880         TLOGE(WmsLogTag::WMS_LIFE, "newSession or property is nullptr");
3881         return;
3882     }
3883     if (SessionHelper::IsSystemWindow(type)) {
3884         if (type == WindowType::WINDOW_TYPE_FLOAT) {
3885             auto parentSession = GetSceneSession(property->GetParentPersistentId());
3886             if (parentSession != nullptr) {
3887                 newSession->SetParentSession(parentSession);
3888             }
3889         }
3890         if (type == WindowType::WINDOW_TYPE_TOAST) {
3891             NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
3892         }
3893         if (type != WindowType::WINDOW_TYPE_DIALOG) {
3894             if (WindowHelper::IsSystemSubWindow(type)) {
3895                 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3896             } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
3897                 && createKeyboardSessionFunc_) {
3898                 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
3899             } else if (createSystemSessionFunc_) {
3900                 SetFocusedSessionDisplayIdIfNeeded(newSession);
3901                 property->SetDisplayId(newSession->GetSessionProperty()->GetDisplayId());
3902                 createSystemSessionFunc_(newSession);
3903             }
3904             TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
3905                 newSession->GetPersistentId(), type);
3906         } else {
3907             TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, "
3908                 "type:%{public}d", newSession->GetPersistentId(), type);
3909             return;
3910         }
3911     } else if (SessionHelper::IsSubWindow(type)) {
3912         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3913         TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
3914             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
3915     } else {
3916         TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
3917             newSession->GetPersistentId(), type);
3918     }
3919 }
3920 
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)3921 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
3922 {
3923     if (session == nullptr) {
3924         TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
3925         return;
3926     }
3927     auto iter = createSubSessionFuncMap_.find(persistentId);
3928     if (iter == createSubSessionFuncMap_.end()) {
3929         recoverSubSessionCacheMap_[persistentId].push_back(session);
3930         TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
3931         return;
3932     }
3933     const auto& createSubSessionFunc = iter->second;
3934     sptr<SceneSession> parentSession = nullptr;
3935     if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
3936         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3937         parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
3938     } else {
3939         parentSession = GetSceneSession(persistentId);
3940     }
3941     if (parentSession == nullptr) {
3942         TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
3943             persistentId, session->GetPersistentId());
3944         return;
3945     }
3946     parentSession->AddSubSession(session);
3947     session->SetParentSession(parentSession);
3948     if (createSubSessionFunc) {
3949         createSubSessionFunc(session);
3950     }
3951     TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, subId: %{public}d",
3952         persistentId, session->GetPersistentId());
3953 }
3954 
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)3955 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
3956     const std::map<int32_t, sptr<SceneSession>>& sessionMap)
3957 {
3958     if (persistentId == INVALID_SESSION_ID) {
3959         TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
3960         return nullptr;
3961     }
3962     auto iter = sessionMap.find(persistentId);
3963     if (iter == sessionMap.end()) {
3964         TLOGD(WmsLogTag::WMS_LIFE, "Error found scene session with id: %{public}d", persistentId);
3965         return nullptr;
3966     }
3967     sptr<SceneSession> parentSession = iter->second;
3968     if (parentSession == nullptr) {
3969         TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
3970         return nullptr;
3971     }
3972     bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
3973         parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
3974     if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
3975         TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
3976         return parentSession;
3977     }
3978     return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
3979 }
3980 
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)3981 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
3982 {
3983     if (session == nullptr) {
3984         TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
3985         return;
3986     }
3987 
3988     auto parentSession = GetSceneSession(persistentId);
3989     if (parentSession == nullptr) {
3990         TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
3991             persistentId, session->GetPersistentId());
3992         return;
3993     }
3994     parentSession->AddToastSession(session);
3995     session->SetParentSession(parentSession);
3996     TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, toastId: %{public}d",
3997         persistentId, session->GetPersistentId());
3998 }
3999 
UnregisterSpecificSessionCreateListener(int32_t persistentId)4000 void SceneSessionManager::UnregisterSpecificSessionCreateListener(int32_t persistentId)
4001 {
4002     TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
4003     taskScheduler_->PostSyncTask([this, persistentId]() {
4004         if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
4005             createSubSessionFuncMap_.erase(persistentId);
4006         }
4007         if (bindDialogTargetFuncMap_.find(persistentId) != bindDialogTargetFuncMap_.end()) {
4008             bindDialogTargetFuncMap_.erase(persistentId);
4009         }
4010         return WMError::WM_OK;
4011     }, __func__);
4012 }
4013 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)4014 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
4015 {
4016     if (!func) {
4017         TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4018     }
4019     statusBarEnabledChangeFunc_ = func;
4020 }
4021 
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)4022 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
4023     const ProcessGestureNavigationEnabledChangeFunc& func)
4024 {
4025     if (!func) {
4026         TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4027     }
4028     gestureNavigationEnabledChangeFunc_ = func;
4029 }
4030 
OnOutsideDownEvent(int32_t x,int32_t y)4031 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
4032 {
4033     TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
4034     if (outsideDownEventFunc_) {
4035         outsideDownEventFunc_(x, y);
4036     }
4037 }
4038 
NotifySessionTouchOutside(int32_t persistentId)4039 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
4040 {
4041     auto task = [this, persistentId]() {
4042         int32_t callingSessionId = INVALID_WINDOW_ID;
4043         auto sceneSession = GetSceneSession(persistentId);
4044         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
4045             callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
4046             TLOGND(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
4047                 persistentId, callingSessionId);
4048         }
4049         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4050         for (const auto& [_, sceneSession] : sceneSessionMap_) {
4051             if (sceneSession == nullptr) {
4052                 continue;
4053             }
4054             if (!(sceneSession->IsVisible() ||
4055                   sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4056                   sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
4057                 continue;
4058             }
4059             auto sessionId = sceneSession->GetPersistentId();
4060             if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
4061                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
4062                 TLOGND(WmsLogTag::WMS_KEYBOARD, "id: %{public}d is not in touchOutsideListenerNodes, don't notify.",
4063                     sessionId);
4064                 continue;
4065             }
4066             if (sessionId == callingSessionId || sessionId == persistentId) {
4067                 TLOGND(WmsLogTag::WMS_KEYBOARD, "No need to notify touch window, id: %{public}d", sessionId);
4068                 continue;
4069             }
4070             sceneSession->NotifyTouchOutside();
4071         }
4072     };
4073 
4074     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
4075     return;
4076 }
4077 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)4078 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
4079 {
4080     TLOGD(WmsLogTag::WMS_EVENT, "in");
4081     outsideDownEventFunc_ = func;
4082 }
4083 
NotifyWatchGestureConsumeResult(int32_t keyCode,bool isConsumed)4084 WMError SceneSessionManager::NotifyWatchGestureConsumeResult(int32_t keyCode, bool isConsumed)
4085 {
4086     TLOGD(WmsLogTag::WMS_EVENT, "keyCode:%{public}d isConsumed:%{public}d", keyCode, isConsumed);
4087     if (onWatchGestureConsumeResultFunc_) {
4088         onWatchGestureConsumeResultFunc_(keyCode, isConsumed);
4089     } else {
4090         TLOGE(WmsLogTag::WMS_EVENT, "onWatchGestureConsumeResultFunc is null");
4091         return WMError::WM_ERROR_INVALID_PARAM;
4092     }
4093     return WMError::WM_OK;
4094 }
4095 
RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc && func)4096 void SceneSessionManager::RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc&& func)
4097 {
4098     TLOGD(WmsLogTag::WMS_EVENT, "in");
4099     onWatchGestureConsumeResultFunc_ = std::move(func);
4100 }
4101 
NotifyWatchFocusActiveChange(bool isActive)4102 WMError SceneSessionManager::NotifyWatchFocusActiveChange(bool isActive)
4103 {
4104     TLOGD(WmsLogTag::WMS_EVENT, "isActive:%{public}d", isActive);
4105     if (onWatchFocusActiveChangeFunc_) {
4106         onWatchFocusActiveChangeFunc_(isActive);
4107     } else {
4108         TLOGE(WmsLogTag::WMS_EVENT, "onWatchFocusActiveChangeFunc is null");
4109         return WMError::WM_ERROR_INVALID_PARAM;
4110     }
4111     return WMError::WM_OK;
4112 }
4113 
RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc && func)4114 void SceneSessionManager::RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc&& func)
4115 {
4116     TLOGD(WmsLogTag::WMS_EVENT, "in");
4117     onWatchFocusActiveChangeFunc_ = std::move(func);
4118 }
4119 
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)4120 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
4121 {
4122     for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
4123         if (iter->second != persistentId) {
4124             continue;
4125         }
4126         if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
4127             TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
4128         }
4129         remoteObjectMap_.erase(iter);
4130         break;
4131     }
4132 }
4133 
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)4134 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
4135 {
4136     auto sceneSession = GetSceneSession(persistentId);
4137     if (sceneSession == nullptr) {
4138         return WSError::WS_ERROR_NULLPTR;
4139     }
4140     auto ret = sceneSession->UpdateActiveStatus(false);
4141     WindowDestroyNotifyVisibility(sceneSession);
4142     auto windowType = sceneSession->GetWindowType();
4143     if (windowType == WindowType::WINDOW_TYPE_DIALOG) {
4144         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4145         if (parentSession == nullptr) {
4146             TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
4147         } else {
4148             parentSession->RemoveDialogToParentSession(sceneSession);
4149             parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4150         }
4151     } else if (windowType == WindowType::WINDOW_TYPE_TOAST) {
4152         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4153         if (parentSession != nullptr) {
4154             TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
4155             parentSession->RemoveToastSession(persistentId);
4156         } else {
4157             TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
4158         }
4159     } else if (windowType == WindowType::WINDOW_TYPE_FLOAT) {
4160         DestroySubSession(sceneSession);
4161     }
4162     ret = sceneSession->Disconnect();
4163     sceneSession->ClearSpecificSessionCbMap();
4164     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
4165         DestroySubSession(sceneSession);
4166         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4167         if (parentSession != nullptr) {
4168             TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
4169             parentSession->RemoveSubSession(sceneSession->GetPersistentId());
4170             parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4171         } else {
4172             TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
4173         }
4174         DestroyUIServiceExtensionSubWindow(sceneSession);
4175     }
4176     {
4177         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4178         EraseSceneSessionAndMarkDirtyLocked(persistentId);
4179         systemTopSceneSessionMap_.erase(persistentId);
4180         nonSystemFloatSceneSessionMap_.erase(persistentId);
4181         UnregisterSpecificSessionCreateListener(persistentId);
4182     }
4183     ClearSpecificSessionRemoteObjectMap(persistentId);
4184     TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
4185     return ret;
4186 }
4187 
DestroyAndDisconnectSpecificSession(const int32_t persistentId)4188 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
4189 {
4190     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4191     auto task = [this, persistentId, callingPid]() {
4192         TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4193         auto sceneSession = GetSceneSession(persistentId);
4194         if (sceneSession == nullptr) {
4195             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4196             return WSError::WS_ERROR_NULLPTR;
4197         }
4198 
4199         if (callingPid != sceneSession->GetCallingPid()) {
4200             TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4201             return WSError::WS_ERROR_INVALID_PERMISSION;
4202         }
4203         return DestroyAndDisconnectSpecificSessionInner(persistentId);
4204     };
4205 
4206     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4207 }
4208 
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)4209 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
4210     const sptr<IRemoteObject>& callback)
4211 {
4212     if (callback == nullptr) {
4213         return WSError::WS_ERROR_NULLPTR;
4214     }
4215     const auto callingPid = IPCSkeleton::GetCallingRealPid();
4216     auto task = [this, persistentId, callingPid, callback]() {
4217         TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4218         auto sceneSession = GetSceneSession(persistentId);
4219         if (sceneSession == nullptr) {
4220             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4221             return WSError::WS_ERROR_NULLPTR;
4222         }
4223 
4224         if (callingPid != sceneSession->GetCallingPid()) {
4225             TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4226             return WSError::WS_ERROR_INVALID_PERMISSION;
4227         }
4228         sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
4229         return DestroyAndDisconnectSpecificSessionInner(persistentId);
4230     };
4231 
4232     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4233 }
4234 
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)4235 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
4236 {
4237     if (!sceneSession) {
4238         TLOGE(WmsLogTag::WMS_SUB, "sceneSession is null");
4239         return;
4240     }
4241     auto sessionProperty = sceneSession->GetSessionProperty();
4242     if (sessionProperty->GetIsUIExtFirstSubWindow() &&
4243         !sessionProperty->GetIsUIExtensionAbilityProcess()) {
4244         sceneSession->NotifyDestroy();
4245         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
4246             TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
4247         TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
4248             sceneSession->GetPersistentId(), errCode);
4249     }
4250 }
4251 
GetWindowSceneConfig() const4252 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
4253 {
4254     return appWindowSceneConfig_;
4255 }
4256 
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)4257 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
4258 {
4259     taskScheduler_->PostAsyncTask([this, config] {
4260         TLOGNI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
4261         rotateAnimationConfig_.duration_ = config.duration_;
4262     }, __func__);
4263 }
4264 
ProcessBackEvent()4265 WSError SceneSessionManager::ProcessBackEvent()
4266 {
4267     taskScheduler_->PostAsyncTask([this]() {
4268         auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
4269         if (focusGroup == nullptr) {
4270             TLOGNE(WmsLogTag::WMS_MAIN, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
4271             return WSError::WS_ERROR_NULLPTR;
4272         }
4273         auto focusedSessionId = focusGroup->GetFocusedSessionId();
4274         auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
4275         auto session = GetSceneSession(focusedSessionId);
4276         if (!session) {
4277             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId);
4278             return WSError::WS_ERROR_INVALID_SESSION;
4279         }
4280         TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
4281             focusedSessionId, needBlockNotifyFocusStatusUntilForeground);
4282         if (needBlockNotifyFocusStatusUntilForeground ||
4283             (!session->IsSessionValid() && !session->IsSystemSession())) {
4284             TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
4285             if (session->GetSessionInfo().abilityInfo != nullptr &&
4286                 session->GetSessionInfo().abilityInfo->unclearableMission) {
4287                 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
4288                 return WSError::WS_OK;
4289             }
4290             session->RequestSessionBack(true);
4291             return WSError::WS_OK;
4292         }
4293         if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
4294             rootSceneProcessBackEventFunc_();
4295         } else {
4296             session->ProcessBackEvent();
4297         }
4298         return WSError::WS_OK;
4299     }, __func__);
4300     return WSError::WS_OK;
4301 }
4302 
InitUserInfo(int32_t userId,std::string & fileDir)4303 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
4304 {
4305     if (userId == DEFAULT_USERID || fileDir.empty()) {
4306         TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
4307         return WSError::WS_DO_NOTHING;
4308     }
4309     TLOGI(WmsLogTag::WMS_MAIN, "userId: %{public}d, path: %{public}s", userId, fileDir.c_str());
4310     return taskScheduler_->PostSyncTask([this, userId, &fileDir]() {
4311         if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
4312             TLOGND(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
4313         }
4314         if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
4315             TLOGND(WmsLogTag::WMS_MAIN, "Create icon directory failed");
4316         }
4317         currentUserId_ = userId;
4318         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
4319         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
4320             MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
4321         }
4322         AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
4323         RegisterSecSurfaceInfoListener();
4324         RegisterConstrainedModalUIExtInfoListener();
4325         return WSError::WS_OK;
4326     }, __func__);
4327 }
4328 
IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession> & sceneSession,int32_t pid)4329 bool SceneSessionManager::IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)
4330 {
4331     auto sessionState = sceneSession->GetSessionState();
4332     auto isInvalidMainSession = !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
4333                                 sessionState == SessionState::STATE_DISCONNECT ||
4334                                 sessionState == SessionState::STATE_END;
4335     if (isInvalidMainSession) {
4336         TLOGD(WmsLogTag::WMS_MULTI_USER, "persistentId: %{public}d, type: %{public}d, state: %{public}d",
4337             sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState());
4338     }
4339     return sceneSession->GetCallingPid() != pid && IsPcSceneSessionLifecycle(sceneSession) && !isInvalidMainSession;
4340 }
4341 
StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession> & sceneSession,bool isUserActive)4342 WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)
4343 {
4344     auto persistentId = sceneSession->GetPersistentId();
4345     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
4346     if (!isUserActive) {
4347         TLOGI(WmsLogTag::WMS_MULTI_USER,
4348             "MinimizeUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
4349             sceneSession->GetWindowType(), sceneSession->GetSessionState());
4350         bool isFromUser = false;
4351         if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) {
4352             TLOGI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId);
4353             if (!sceneSession->UpdateInteractiveInner(false)) {
4354                 TLOGI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId);
4355             }
4356         }
4357         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(
4358             abilitySessionInfo, isFromUser, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
4359         if (errCode == ERR_OK) {
4360             sceneSession->SetMinimizedFlagByUserSwitch(true);
4361         } else {
4362             TLOGE(WmsLogTag::WMS_MULTI_USER, "minimize failed! errCode: %{public}d", errCode);
4363         }
4364     } else if (sceneSession->IsMinimizedByUserSwitch()) {
4365         TLOGI(WmsLogTag::WMS_MULTI_USER,
4366             "StartUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
4367             sceneSession->GetWindowType(), sceneSession->GetSessionState());
4368         sceneSession->SetMinimizedFlagByUserSwitch(false);
4369         bool isColdStart = false;
4370         abilitySessionInfo->isNewWant = false;
4371         int32_t errCode = StartUIAbilityBySCBTimeoutCheck(
4372             abilitySessionInfo, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH), isColdStart);
4373         if (errCode != ERR_OK) {
4374             TLOGE(WmsLogTag::WMS_MULTI_USER, "start failed! errCode: %{public}d", errCode);
4375             ExceptionInfo exceptionInfo;
4376             exceptionInfo.needRemoveSession = true;
4377             sceneSession->NotifySessionExceptionInner(abilitySessionInfo, exceptionInfo, false, true);
4378             if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
4379                 startUIAbilityErrorFunc_(
4380                     static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
4381             }
4382         }
4383     }
4384     return WSError::WS_OK;
4385 }
4386 
ProcessUIAbilityOnUserSwitch(bool isUserActive)4387 void SceneSessionManager::ProcessUIAbilityOnUserSwitch(bool isUserActive)
4388 {
4389     int32_t pid = GetPid();
4390     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4391     for (const auto& [_, sceneSession] : sceneSessionMap_) {
4392         if (sceneSession == nullptr) {
4393             TLOGE(WmsLogTag::WMS_MULTI_USER, "session is null");
4394             continue;
4395         }
4396         // Change app life cycle in pc when user switch, do app freeze or unfreeze
4397         if (IsNeedChangeLifeCycleOnUserSwitch(sceneSession, pid)) {
4398             StartOrMinimizeUIAbilityBySCB(sceneSession, isUserActive);
4399         }
4400     }
4401 }
4402 
HandleUserSwitching(bool isUserActive)4403 void SceneSessionManager::HandleUserSwitching(bool isUserActive)
4404 {
4405     isUserBackground_ = !isUserActive;
4406     SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
4407     if (isUserActive) { // switch to current user
4408         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
4409         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
4410             MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
4411         }
4412         AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
4413         // notify screenSessionManager to recover current user
4414         ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
4415         FlushWindowInfoToMMI(true);
4416         NotifyAllAccessibilityInfo();
4417         rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
4418         UpdatePrivateStateAndNotifyForAllScreens();
4419     } else { // switch to another user
4420         SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
4421         rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
4422         // minimized UI abilities when the user is switching and inactive
4423         ProcessUIAbilityOnUserSwitch(isUserActive);
4424     }
4425 }
4426 
HandleUserSwitched(bool isUserActive)4427 void SceneSessionManager::HandleUserSwitched(bool isUserActive)
4428 {
4429     if (isUserActive) {
4430         // start UI abilities only after the user has switched and become active
4431         ProcessUIAbilityOnUserSwitch(isUserActive);
4432     }
4433 }
4434 
HandleUserSwitch(const UserSwitchEventType type,const bool isUserActive)4435 void SceneSessionManager::HandleUserSwitch(const UserSwitchEventType type, const bool isUserActive)
4436 {
4437     if (type == UserSwitchEventType::SWITCHING && !isUserActive) {
4438         ScreenSessionManagerClient::GetInstance().DisconnectAllExternalScreen();
4439     }
4440     taskScheduler_->PostSyncTask([this, type, isUserActive, where = __func__] {
4441         TLOGNI(WmsLogTag::WMS_MULTI_USER,
4442                "%{public}s: currentUserId: %{public}d, switchEventType: %{public}u, isUserActive: %{public}u",
4443                where, currentUserId_.load(), type, isUserActive);
4444         if (type == UserSwitchEventType::SWITCHING) {
4445             HandleUserSwitching(isUserActive);
4446         } else {
4447             HandleUserSwitched(isUserActive);
4448         }
4449         return WSError::WS_OK;
4450     }, __func__);
4451 }
4452 
GetBundleManager()4453 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
4454 {
4455     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
4456     if (systemAbilityMgr == nullptr) {
4457         TLOGE(WmsLogTag::DEFAULT, "Failed to get SystemAbilityManager.");
4458         return nullptr;
4459     }
4460     auto bmsProxy = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
4461     if (bmsProxy == nullptr) {
4462         TLOGE(WmsLogTag::DEFAULT, "Failed to get BundleManagerService.");
4463         return nullptr;
4464     }
4465     return iface_cast<AppExecFwk::IBundleMgr>(bmsProxy);
4466 }
4467 
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)4468 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
4469     const AppExecFwk::AbilityInfo& abilityInfo)
4470 {
4471     auto context = rootSceneContextWeak_.lock();
4472     if (!context) {
4473         TLOGE(WmsLogTag::DEFAULT, "context is nullptr.");
4474         return nullptr;
4475     }
4476     auto resourceMgr = context->GetResourceManager();
4477     if (!resourceMgr) {
4478         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
4479         return nullptr;
4480     }
4481     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
4482     if (!resConfig) {
4483         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
4484         return nullptr;
4485     }
4486     resourceMgr->GetResConfig(*resConfig);
4487     resourceMgr = Global::Resource::CreateResourceManager(
4488         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
4489     if (!resourceMgr) {
4490         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
4491         return nullptr;
4492     }
4493     resourceMgr->UpdateResConfig(*resConfig);
4494 
4495     std::string loadPath;
4496     if (!abilityInfo.hapPath.empty()) { // zipped hap
4497         loadPath = abilityInfo.hapPath;
4498     } else {
4499         loadPath = abilityInfo.resourcePath;
4500     }
4501 
4502     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
4503         TLOGW(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
4504     }
4505     return resourceMgr;
4506 }
4507 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)4508 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
4509     std::string& path, uint32_t& bgColor)
4510 {
4511     auto resourceMgr = GetResourceManager(abilityInfo);
4512     if (!resourceMgr) {
4513         TLOGE(WmsLogTag::WMS_PATTERN, "resourceMgr is nullptr.");
4514         return false;
4515     }
4516 
4517     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
4518         TLOGE(WmsLogTag::WMS_PATTERN, "Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
4519         return false;
4520     }
4521 
4522     if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
4523         TLOGE(WmsLogTag::WMS_PATTERN, "Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
4524         return false;
4525     }
4526 
4527     if (!abilityInfo.hapPath.empty()) { // zipped hap
4528         auto pos = path.find_last_of('.');
4529         if (pos == std::string::npos) {
4530             TLOGE(WmsLogTag::WMS_PATTERN, "Format error, path %{private}s.", path.c_str());
4531             return false;
4532         }
4533         path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
4534     }
4535     return true;
4536 }
4537 
GetIconFromDesk(const SessionInfo & sessionInfo,std::string & startupPagePath) const4538 bool SceneSessionManager::GetIconFromDesk(const SessionInfo& sessionInfo, std::string& startupPagePath) const
4539 {
4540     auto& want = sessionInfo.want;
4541     if (want == nullptr) {
4542         TLOGI(WmsLogTag::WMS_PATTERN, "want is nullPtr");
4543         return false;
4544     }
4545     startupPagePath = want->GetStringParam("realAppIcon");
4546     if (startupPagePath.empty()) {
4547         return false;
4548     }
4549     return true;
4550 }
4551 
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)4552 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
4553 {
4554     if (GetIconFromDesk(sessionInfo, path)) {
4555         TLOGI(WmsLogTag::WMS_PATTERN, "get icon from desk success");
4556         return;
4557     }
4558 
4559     if (!bundleMgr_) {
4560         TLOGE(WmsLogTag::WMS_PATTERN, "bundleMgr_ is nullptr.");
4561         return;
4562     }
4563     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
4564     if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
4565         TLOGW(WmsLogTag::WMS_PATTERN, "Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
4566         return;
4567     }
4568     AAFwk::Want want;
4569     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
4570     AppExecFwk::AbilityInfo abilityInfo;
4571     if (!bundleMgr_->QueryAbilityInfo(
4572         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
4573         TLOGE(WmsLogTag::WMS_PATTERN, "Get ability info from BMS failed!");
4574         return;
4575     }
4576 
4577     if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
4578         CacheStartingWindowInfo(abilityInfo, path, bgColor);
4579     }
4580     TLOGW(WmsLogTag::WMS_PATTERN, "%{public}d, %{public}d, %{public}s, %{public}x",
4581         abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
4582 }
4583 
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)4584 bool SceneSessionManager::GetStartingWindowInfoFromCache(
4585     const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
4586 {
4587     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
4588     std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4589     auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
4590     if (iter == startingWindowMap_.end()) {
4591         return false;
4592     }
4593     auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
4594     const auto& infoMap = iter->second;
4595     auto infoMapIter = infoMap.find(key);
4596     if (infoMapIter == infoMap.end()) {
4597         return false;
4598     }
4599     path = infoMapIter->second.startingWindowIconPath_;
4600     bgColor = infoMapIter->second.startingWindowBackgroundColor_;
4601     return true;
4602 }
4603 
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)4604 void SceneSessionManager::CacheStartingWindowInfo(
4605     const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
4606 {
4607     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
4608     auto key = abilityInfo.moduleName + abilityInfo.name;
4609     StartingWindowInfo info = {
4610         .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
4611         .startingWindowIconId_ = abilityInfo.startWindowIconId,
4612         .startingWindowBackgroundColor_ = bgColor,
4613         .startingWindowIconPath_ = path,
4614     };
4615     std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4616     auto iter = startingWindowMap_.find(abilityInfo.bundleName);
4617     if (iter != startingWindowMap_.end()) {
4618         auto& infoMap = iter->second;
4619         infoMap.emplace(key, info);
4620         return;
4621     }
4622     if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
4623         startingWindowMap_.erase(startingWindowMap_.begin());
4624     }
4625     std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
4626     startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
4627 }
4628 
OnBundleUpdated(const std::string & bundleName,int userId)4629 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
4630 {
4631     taskScheduler_->PostAsyncTask([this, bundleName]() {
4632         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4633         if (auto iter = startingWindowMap_.find(bundleName); iter != startingWindowMap_.end()) {
4634             startingWindowMap_.erase(iter);
4635         }
4636     }, __func__);
4637 }
4638 
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4639 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4640 {
4641     taskScheduler_->PostAsyncTask([this]() {
4642         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4643         startingWindowMap_.clear();
4644     }, __func__);
4645 }
4646 
FillSessionInfo(sptr<SceneSession> & sceneSession)4647 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
4648 {
4649     const auto& sessionInfo = sceneSession->GetSessionInfo();
4650     if (sessionInfo.bundleName_.empty()) {
4651         TLOGE(WmsLogTag::DEFAULT, "bundleName_ is empty");
4652         return;
4653     }
4654     if (sessionInfo.isSystem_) {
4655         TLOGD(WmsLogTag::DEFAULT, "is system scene!");
4656         return;
4657     }
4658     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
4659         sessionInfo.moduleName_);
4660     if (abilityInfo == nullptr) {
4661         TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
4662         return;
4663     }
4664     sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
4665     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
4666     sceneSession->SetSessionInfoTime(GetCurrentTime());
4667     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
4668         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
4669     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
4670         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
4671     }
4672     TLOGI(WmsLogTag::WMS_MAIN, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
4673         "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
4674         abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
4675         abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
4676 }
4677 
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)4678 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
4679     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
4680 {
4681     if (!bundleMgr_) {
4682         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
4683         return nullptr;
4684     }
4685     SessionInfoList list = {
4686         .uid_ = uId, .bundleName_ = bundleName, .abilityName_ = abilityName, .moduleName_ = moduleName
4687     };
4688     if (abilityInfoMap_.count(list)) {
4689         return abilityInfoMap_[list];
4690     }
4691     AAFwk::Want want;
4692     want.SetElementName("", bundleName, abilityName, moduleName);
4693     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
4694     if (abilityInfo == nullptr) {
4695         TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
4696         return nullptr;
4697     }
4698     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
4699         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
4700         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
4701     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
4702     if (!ret) {
4703         TLOGE(WmsLogTag::DEFAULT, "Get ability info from BMS failed!");
4704         return nullptr;
4705     }
4706     abilityInfoMap_[list] = abilityInfo;
4707     return abilityInfo;
4708 }
4709 
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)4710 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
4711     uint32_t& topWinId, uint32_t& zOrder)
4712 {
4713     const auto& subVec = session->GetSubSession();
4714     for (const auto& subSession : subVec) {
4715         if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
4716             TLOGW(WmsLogTag::WMS_SUB,
4717                 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
4718             continue;
4719         }
4720         if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4721              subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
4722             subSession->GetZOrder() > zOrder) {
4723             topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
4724             zOrder = subSession->GetZOrder();
4725             TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
4726                 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
4727         }
4728         if (subSession->GetSubSession().size() > 0) {
4729             GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
4730         }
4731     }
4732 }
4733 
4734 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)4735 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
4736 {
4737     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4738     auto task = [this, mainWinId, &topWinId, callingPid]() {
4739         const auto& mainSession = GetSceneSession(mainWinId);
4740         if (mainSession == nullptr) {
4741             return WMError::WM_ERROR_INVALID_WINDOW;
4742         }
4743 
4744         if (callingPid != mainSession->GetCallingPid()) {
4745             TLOGNE(WmsLogTag::WMS_HIERARCHY, "Permission denied, not destroy by the same process");
4746             return WMError::WM_ERROR_INVALID_PERMISSION;
4747         }
4748         uint32_t zOrder = mainSession->GetZOrder();
4749         topWinId = mainWinId;
4750         GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
4751         TLOGNI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
4752             "zOrder: %{public}d", mainWinId, topWinId, zOrder);
4753         return WMError::WM_OK;
4754     };
4755 
4756     if (!Session::IsScbCoreEnabled()) {
4757         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4758     }
4759     bool postNow = false;
4760     auto mainSession = GetSceneSession(mainWinId);
4761     if (mainSession != nullptr) {
4762         postNow = !(mainSession->GetUIStateDirty());
4763     }
4764     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
4765     if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
4766         taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
4767         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4768     }
4769     TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
4770     {
4771         std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
4772         if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
4773             std::cv_status::timeout) {
4774             TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
4775         }
4776     }
4777     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4778 }
4779 
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)4780 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
4781     int32_t windowId, int32_t& mainWindowId)
4782 {
4783     auto iter = sceneSessionMap.find(windowId);
4784     if (iter == sceneSessionMap.end()) {
4785         TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
4786         return WMError::WM_ERROR_NULLPTR;
4787     }
4788     sptr<SceneSession> sceneSession = iter->second;
4789     if (sceneSession == nullptr) {
4790         TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
4791         return WMError::WM_ERROR_NULLPTR;
4792     }
4793     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
4794         mainWindowId = sceneSession->GetPersistentId();
4795         return WMError::WM_OK;
4796     }
4797     if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4798         WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
4799         return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
4800     }
4801     // not sub window, dialog, return invalid id
4802     mainWindowId = INVALID_SESSION_ID;
4803     return WMError::WM_OK;
4804 }
4805 
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)4806 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
4807 {
4808     if (windowId == INVALID_SESSION_ID) {
4809         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
4810         return WMError::WM_ERROR_INVALID_PARAM;
4811     }
4812     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4813     return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
4814 }
4815 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4816 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
4817     const sptr<SceneSession>& sceneSession)
4818 {
4819     auto systemBarProperties = property->GetSystemBarProperty();
4820     for (auto iter : systemBarProperties) {
4821         if (iter.first == type) {
4822             sceneSession->SetSystemBarProperty(iter.first, iter.second);
4823             TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d enable %{public}d",
4824                 static_cast<int32_t>(iter.first), iter.second.enable_);
4825         }
4826     }
4827     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4828 }
4829 
4830 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4831 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
4832     const sptr<SceneSession>& sceneSession)
4833 {
4834     if (!SessionPermission::IsSystemCalling()) {
4835         TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
4836         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4837     }
4838 
4839     sceneSession->SetTopmost(property->IsTopmost());
4840     return WMError::WM_OK;
4841 }
4842 
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4843 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
4844     const sptr<SceneSession>& sceneSession)
4845 {
4846     auto propertyOld = sceneSession->GetSessionProperty();
4847     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
4848     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
4849     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
4850         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "property hideNonSystemFloatingWindows not change");
4851         return;
4852     }
4853 
4854     if (IsSessionVisibleForeground(sceneSession)) {
4855         if (hideNonSystemFloatingWindowsOld) {
4856             UpdateForceHideState(sceneSession, propertyOld, false);
4857         } else {
4858             UpdateForceHideState(sceneSession, property, true);
4859         }
4860     }
4861 }
4862 
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)4863 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
4864     const sptr<WindowSessionProperty>& property, bool add)
4865 {
4866     if (systemConfig_.IsPcWindow()) {
4867         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "IsPcWindow, ineffective");
4868         return;
4869     }
4870     if (property == nullptr) {
4871         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "property is null");
4872         return;
4873     }
4874     auto persistentId = sceneSession->GetPersistentId();
4875     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
4876     bool notifyAll = false;
4877     if (add) {
4878         if (property->GetHideNonSystemFloatingWindows()) {
4879             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
4880             notifyAll = !forceHideFloatOld;
4881         } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
4882             sceneSession->GetIsAncoForFloatingWindow()) {
4883             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
4884             if (forceHideFloatOld) {
4885                 sceneSession->NotifyForceHideChange(true);
4886             }
4887         }
4888     } else {
4889         if (property->GetHideNonSystemFloatingWindows()) {
4890             systemTopSceneSessionMap_.erase(persistentId);
4891             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
4892         } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
4893             sceneSession->GetIsAncoForFloatingWindow()) {
4894             nonSystemFloatSceneSessionMap_.erase(persistentId);
4895             if (property->GetForceHide()) {
4896                 sceneSession->NotifyForceHideChange(false);
4897             }
4898         }
4899     }
4900     if (notifyAll) {
4901         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
4902         for (const auto& item : nonSystemFloatSceneSessionMap_) {
4903             auto forceHideSceneSession = item.second;
4904             if (forceHideFloatNew != forceHideSceneSession->GetSessionProperty()->GetForceHide()) {
4905                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
4906             }
4907         }
4908     }
4909 }
4910 
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)4911 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
4912 {
4913 #ifdef POWER_MANAGER_ENABLE
4914     auto task = [this, sceneSession]() {
4915         if (sceneSession == nullptr) {
4916             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4917             return;
4918         }
4919         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Win: %{public}s, is turn on%{public}d",
4920             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4921         std::string identity = IPCSkeleton::ResetCallingIdentity();
4922         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
4923             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "turn screen on");
4924             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4925         }
4926         // set ipc identity to raw
4927         IPCSkeleton::SetCallingIdentity(identity);
4928     };
4929     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
4930 
4931 #else
4932     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
4933 #endif
4934 }
4935 
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock,const std::string & screenLockPrefix,std::shared_ptr<PowerMgr::RunningLock> & screenLock)4936 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock,
4937     const std::string& screenLockPrefix, std::shared_ptr<PowerMgr::RunningLock>& screenLock)
4938 {
4939 #ifdef POWER_MANAGER_ENABLE
4940     wptr<SceneSession> weakSceneSession(sceneSession);
4941     auto task = [this, weakSceneSession, requireLock, &screenLockPrefix, &screenLock]() {
4942         auto sceneSession = weakSceneSession.promote();
4943         if (sceneSession == nullptr) {
4944             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4945             return;
4946         }
4947         if (requireLock && screenLock == nullptr) {
4948             // reset ipc identity
4949             std::string identity = IPCSkeleton::ResetCallingIdentity();
4950             screenLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
4951                 screenLockPrefix + std::to_string(sceneSession->GetPersistentId()),
4952                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
4953             // set ipc identity to raw
4954             IPCSkeleton::SetCallingIdentity(identity);
4955         }
4956         if (screenLock == nullptr) {
4957             return;
4958         }
4959         auto currScreenId = sceneSession->GetSessionInfo().screenId_;
4960         auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
4961         if (auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currScreenId)) {
4962             sourceMode = screenSession->GetSourceMode();
4963         }
4964         bool shouldLock = requireLock && IsSessionVisibleForeground(sceneSession) && sourceMode != ScreenSourceMode::SCREEN_UNIQUE;
4965         TLOGNI(WmsLogTag::WMS_ATTRIBUTE,
4966             "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d]",
4967             sceneSession->GetWindowName().c_str(), sceneSession->GetSessionState(),
4968             sceneSession->IsVisible(), requireLock, shouldLock, currScreenId, sourceMode);
4969         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
4970         ErrCode res;
4971         std::string identity = IPCSkeleton::ResetCallingIdentity();
4972         if (shouldLock) {
4973             res = screenLock->Lock();
4974         } else {
4975             res = screenLock->UnLock();
4976         }
4977         // set ipc identity to raw
4978         IPCSkeleton::SetCallingIdentity(identity);
4979         if (res != ERR_OK) {
4980             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "handle keep screen running lock failed: [operation: %{public}d, "
4981                 "err: %{public}d]", requireLock, res);
4982         }
4983     };
4984     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
4985 #else
4986     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
4987 #endif
4988 }
4989 
NotifyVisibleChange(int32_t persistentId)4990 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
4991 {
4992     auto sceneSession = GetSceneSession(persistentId);
4993     if (sceneSession == nullptr) {
4994         return false;
4995     }
4996     HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
4997                        sceneSession->keepScreenLock_);
4998     HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
4999                        sceneSession->viewKeepScreenLock_);
5000     return true;
5001 }
5002 
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)5003 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
5004 {
5005 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
5006     if (GetDisplayBrightness() != brightness &&
5007         GetFocusedSessionId() == sceneSession->GetPersistentId()) {
5008         PostBrightnessTask(brightness);
5009     }
5010 #else
5011     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of DisplayPowerMgr");
5012 #endif
5013     brightnessSessionId_ = sceneSession->GetPersistentId();
5014     return WSError::WS_OK;
5015 }
5016 
PostBrightnessTask(float brightness)5017 void SceneSessionManager::PostBrightnessTask(float brightness)
5018 {
5019     bool postTaskRet = true;
5020     bool isPC = systemConfig_.IsPcWindow();
5021     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
5022         if (!isPC) {
5023             auto task = [] {
5024                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
5025             };
5026             postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
5027         }
5028         SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
5029     } else {
5030         auto task = [brightness, isPC] {
5031             if (isPC) {
5032                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
5033                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
5034             } else {
5035                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
5036                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
5037             }
5038         };
5039         postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
5040         SetDisplayBrightness(brightness);
5041     }
5042     if (!postTaskRet) {
5043         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
5044     }
5045 }
5046 
UpdateBrightness(int32_t persistentId)5047 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
5048 {
5049     if (systemConfig_.IsPcWindow()) {
5050         return WSError::WS_OK;
5051     }
5052     auto sceneSession = GetSceneSession(persistentId);
5053     if (sceneSession == nullptr) {
5054         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
5055         return WSError::WS_ERROR_NULLPTR;
5056     }
5057     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
5058           sceneSession->GetSessionInfo().isSystem_)) {
5059         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
5060         return WSError::WS_DO_NOTHING;
5061     }
5062     auto brightness = sceneSession->GetBrightness();
5063     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
5064     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
5065         if (IsNeedUpdateBrightness(brightness)) {
5066             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
5067             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
5068             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
5069             brightnessSessionId_ = INVALID_WINDOW_ID;
5070         }
5071     } else {
5072         if (std::fabs(brightness - GetDisplayBrightness()) > std::numeric_limits<float>::min()) {
5073             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
5074             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
5075                 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
5076             SetDisplayBrightness(brightness);
5077         }
5078         brightnessSessionId_ = sceneSession->GetPersistentId();
5079     }
5080     return WSError::WS_OK;
5081 }
5082 
IsNeedUpdateBrightness(float brightness)5083 bool SceneSessionManager::IsNeedUpdateBrightness(float brightness)
5084 {
5085     if (std::fabs(brightness - GetDisplayBrightness()) < std::numeric_limits<float>::min()) {
5086         return false;
5087     }
5088     auto sceneSession = GetSceneSession(brightnessSessionId_);
5089     if (sceneSession != nullptr && sceneSession->IsSessionForeground()) {
5090         return false;
5091     }
5092     return true;
5093 }
5094 
GetCurrentUserId() const5095 int32_t SceneSessionManager::GetCurrentUserId() const
5096 {
5097     return currentUserId_;
5098 }
5099 
SetDisplayBrightness(float brightness)5100 void SceneSessionManager::SetDisplayBrightness(float brightness)
5101 {
5102     displayBrightness_ = brightness;
5103 }
5104 
GetDisplayBrightness() const5105 float SceneSessionManager::GetDisplayBrightness() const
5106 {
5107     return displayBrightness_;
5108 }
5109 
SetGestureNavigationEnabled(bool enable)5110 WMError SceneSessionManager::SetGestureNavigationEnabled(bool enable)
5111 {
5112     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5113         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
5114         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5115     }
5116     std::string callerBundleName = SessionPermission::GetCallingBundleName();
5117     TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
5118     auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
5119         SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
5120         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
5121             TLOGNE(WmsLogTag::WMS_EVENT, "callback func is null");
5122             return WMError::WM_OK;
5123         }
5124         if (gestureNavigationEnabledChangeFunc_) {
5125             gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
5126         }
5127         if (statusBarEnabledChangeFunc_) {
5128             statusBarEnabledChangeFunc_(enable, bundleName);
5129         }
5130         return WMError::WM_OK;
5131     };
5132     return taskScheduler_->PostSyncTask(task, "SetGestureNavigationEnabled");
5133 }
5134 
SetFocusedSessionId(const int32_t persistentId,const DisplayId displayId)5135 WSError SceneSessionManager::SetFocusedSessionId(const int32_t persistentId, const DisplayId displayId)
5136 {
5137     return windowFocusController_->UpdateFocusedSessionId(displayId, persistentId);
5138 }
5139 
GetFocusedSessionId(DisplayId displayId) const5140 int32_t SceneSessionManager::GetFocusedSessionId(DisplayId displayId) const
5141 {
5142     return windowFocusController_->GetFocusedSessionId(displayId);
5143 }
5144 
GetFocusWindowInfo(FocusChangeInfo & focusInfo,DisplayId displayId)5145 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo, DisplayId displayId)
5146 {
5147     if (!SessionPermission::IsSACalling()) {
5148         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
5149         return;
5150     }
5151     taskScheduler_->PostSyncTask([this, &focusInfo, displayId] {
5152         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
5153         if (focusGroup == nullptr) {
5154             TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
5155             return WSError::WS_ERROR_DESTROYED_OBJECT;
5156         }
5157         if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
5158             focusInfo.windowId_ = sceneSession->GetWindowId();
5159             focusInfo.displayId_ = focusGroup->GetDisplayGroupId();
5160             focusInfo.pid_ = sceneSession->GetCallingPid();
5161             focusInfo.uid_ = sceneSession->GetCallingUid();
5162             focusInfo.windowType_ = sceneSession->GetWindowType();
5163             focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
5164             TLOGNI(WmsLogTag::WMS_FOCUS, "Get focus session info success");
5165             return WSError::WS_OK;
5166         }
5167         return WSError::WS_ERROR_DESTROYED_OBJECT;
5168     }, __func__);
5169 }
5170 
AddFocusGroup(DisplayId displayId)5171 WSError SceneSessionManager::AddFocusGroup(DisplayId displayId)
5172 {
5173     return windowFocusController_->AddFocusGroup(displayId);
5174 }
5175 
RemoveFocusGroup(DisplayId displayId)5176 WSError SceneSessionManager::RemoveFocusGroup(DisplayId displayId)
5177 {
5178     return windowFocusController_->RemoveFocusGroup(displayId);
5179 }
5180 
IsValidDigitString(const std::string & windowIdStr)5181 static bool IsValidDigitString(const std::string& windowIdStr)
5182 {
5183     if (windowIdStr.empty()) {
5184         return false;
5185     }
5186     for (char ch : windowIdStr) {
5187         if (ch >= '0' && ch <= '9') {
5188             continue;
5189         }
5190         TLOGE(WmsLogTag::DEFAULT, "invalid window id");
5191         return false;
5192     }
5193     return true;
5194 }
5195 
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)5196 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
5197 {
5198     if (sceneSession == nullptr) {
5199         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
5200         return;
5201     }
5202     sceneSession->SetSessionExceptionListener([this, where = __func__](
5203         const SessionInfo& info, const ExceptionInfo& exceptionInfo , bool startFail = false) {
5204         auto task = [this, info, where] {
5205             auto session = GetSceneSession(info.persistentId_);
5206             if (session == nullptr) {
5207                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
5208                 return;
5209             }
5210             if (session->GetSessionInfo().isSystem_) {
5211                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where, session->GetPersistentId());
5212                 return;
5213             }
5214             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
5215                 where, info.errorCode, info.persistentId_);
5216             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
5217                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
5218                 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
5219                     "or foreground timeout, id: %{public}d", info.persistentId_);
5220                 listenerController_->NotifySessionClosed(session->GetSessionInfo());
5221             }
5222         };
5223         taskScheduler_->PostVoidSyncTask(task, "sessionException");
5224     }, false);
5225     TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
5226 }
5227 
RegisterVisibilityChangedDetectFunc(const sptr<SceneSession> & sceneSession)5228 void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)
5229 {
5230     if (sceneSession == nullptr) {
5231         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
5232         return;
5233     }
5234     sceneSession->SetVisibilityChangedDetectFunc(
5235         [this](int32_t pid, bool isVisible, bool newIsVisible) THREAD_SAFETY_GUARD(SCENE_GUARD) {
5236         if (isVisible == newIsVisible || pid == -1) {
5237             return;
5238         }
5239         auto windowPidVisibilityInfo = sptr<WindowPidVisibilityInfo>::MakeSptr();
5240         windowPidVisibilityInfo->pid_ = pid;
5241         int32_t currentCount = 0;
5242         int32_t beforeCount = 0;
5243         if (visibleWindowCountMap_.find(pid) != visibleWindowCountMap_.end()) {
5244             beforeCount = visibleWindowCountMap_[pid];
5245         }
5246         currentCount = newIsVisible ? beforeCount + 1 : beforeCount - 1;
5247         visibleWindowCountMap_[pid] = currentCount;
5248         if (visibleWindowCountMap_[pid] == 0) {
5249             visibleWindowCountMap_.erase(pid);
5250         }
5251         if (beforeCount == 0 && currentCount == 1) {
5252             TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid);
5253             windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE;
5254             SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
5255         } else if (beforeCount == 1 && currentCount == 0) {
5256             TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid);
5257             windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE;
5258             SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
5259         } else if (beforeCount < 0 || currentCount < 0) {
5260             TLOGNE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid);
5261             RecoveryVisibilityPidCount(pid);
5262         }
5263     });
5264 }
5265 
RecoveryVisibilityPidCount(int32_t pid)5266 void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid)
5267 {
5268     int32_t count = 0;
5269     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5270     for (const auto& [_, session] : sceneSessionMap_) {
5271         if (session && session->GetCallingPid() == pid && session->IsVisible()) {
5272             count++;
5273         }
5274     }
5275     if (count > 0) {
5276         visibleWindowCountMap_[pid] = count;
5277     }
5278 }
5279 
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)5280 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
5281 {
5282     if (sceneSession == nullptr) {
5283         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5284         return;
5285     }
5286     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
5287         auto sceneSession = GetSceneSession(persistentId);
5288         if (sceneSession == nullptr) {
5289             TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
5290             return;
5291         }
5292         if (sceneSession->GetSessionInfo().isSystem_) {
5293             TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, id: %{public}d is system",
5294                 sceneSession->GetPersistentId());
5295             return;
5296         }
5297         auto abilityInfo = sceneSession->GetSessionInfo().abilityInfo;
5298         if (abilityInfo == nullptr) {
5299             TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, abilityInfo is nullptr");
5300             return;
5301         }
5302         if (!abilityInfo->excludeFromMissions) {
5303             listenerController_->NotifySessionSnapshotChanged(persistentId);
5304         }
5305     };
5306     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
5307     TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d", sceneSession->GetPersistentId());
5308 }
5309 
RegisterRequestVsyncFunc(const sptr<SceneSession> & sceneSession)5310 void SceneSessionManager::RegisterRequestVsyncFunc(const sptr<SceneSession>& sceneSession)
5311 {
5312     if (sceneSession == nullptr) {
5313         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5314         return;
5315     }
5316     sceneSession->SetRequestNextVsyncFunc([this](const std::shared_ptr<VsyncCallback>& callback) {
5317         vsyncStation_->RequestVsync(callback);
5318     });
5319 }
5320 
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)5321 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
5322 {
5323     if (sceneSession == nullptr) {
5324         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5325         return;
5326     }
5327     AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
5328         config.duration_ = rotateAnimationConfig_.duration_;
5329     };
5330     sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
5331     TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d",
5332         sceneSession->GetPersistentId());
5333 }
5334 
NotifySessionForCallback(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)5335 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
5336 {
5337     if (sceneSession == nullptr) {
5338         TLOGW(WmsLogTag::DEFAULT, "session is null");
5339         return;
5340     }
5341     if (sceneSession->GetSessionInfo().isSystem_) {
5342         TLOGW(WmsLogTag::DEFAULT, "id: %{public}d is system", sceneSession->GetPersistentId());
5343         return;
5344     }
5345     if (sceneSession->GetSessionInfo().appIndex_ != 0) {
5346         TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, appIndex: %{public}d, id: %{public}d",
5347                sceneSession->GetSessionInfo().appIndex_, sceneSession->GetPersistentId());
5348         listenerController_->NotifySessionLifecycleEvent(
5349             ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
5350         return;
5351     }
5352     if (needRemoveSession) {
5353         TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, needRemoveSession, id: %{public}d", sceneSession->GetPersistentId());
5354         listenerController_->NotifySessionLifecycleEvent(
5355             ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
5356         return;
5357     }
5358     if (sceneSession->GetSessionInfo().abilityInfo == nullptr) {
5359         TLOGW(WmsLogTag::DEFAULT, "abilityInfo is null, id: %{public}d", sceneSession->GetPersistentId());
5360     } else if ((sceneSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
5361                (sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
5362         TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
5363             sceneSession->GetPersistentId());
5364         listenerController_->NotifySessionLifecycleEvent(
5365             ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
5366         return;
5367     }
5368     TLOGI(WmsLogTag::DEFAULT, "NotifyClosed, id: %{public}d", sceneSession->GetPersistentId());
5369     listenerController_->NotifySessionClosed(sceneSession->GetSessionInfo());
5370 }
5371 
NotifyWindowInfoChangeFromSession(int32_t persistentId)5372 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
5373 {
5374     TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d", persistentId);
5375     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
5376     if (sceneSession == nullptr) {
5377         TLOGE(WmsLogTag::DEFAULT, "sceneSession nullptr");
5378         return;
5379     }
5380 
5381     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
5382 }
5383 
IsSessionVisible(const sptr<SceneSession> & session) const5384 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session) const
5385 {
5386     if (session == nullptr) {
5387         return false;
5388     }
5389     if (Session::IsScbCoreEnabled()) {
5390         return session->IsVisible();
5391     }
5392     const auto& state = session->GetSessionState();
5393     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
5394         const auto& mainOrFloatSession = session->GetMainOrFloatSession();
5395         if (mainOrFloatSession == nullptr) {
5396             TLOGE(WmsLogTag::WMS_SUB, "Can not find parent for this sub window, id: %{public}d",
5397                 session->GetPersistentId());
5398             return false;
5399         }
5400         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
5401             const auto mainOrFloatSessionState = mainOrFloatSession->GetSessionState();
5402             if (mainOrFloatSessionState == SessionState::STATE_INACTIVE ||
5403                 mainOrFloatSessionState == SessionState::STATE_BACKGROUND) {
5404                 TLOGD(WmsLogTag::WMS_SUB, "Parent of this sub window is at background, id: %{public}d",
5405                     session->GetPersistentId());
5406                 return false;
5407             }
5408             TLOGD(WmsLogTag::WMS_SUB, "Sub window is at foreground, id: %{public}d", session->GetPersistentId());
5409             return true;
5410         }
5411         TLOGD(WmsLogTag::WMS_SUB, "Sub window is at background, id: %{public}d", session->GetPersistentId());
5412         return false;
5413     }
5414 
5415     if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
5416         TLOGD(WmsLogTag::WMS_LIFE, "Window is at foreground, id: %{public}d", session->GetPersistentId());
5417         return true;
5418     }
5419     TLOGD(WmsLogTag::WMS_LIFE, "Window is at background, id: %{public}d", session->GetPersistentId());
5420     return false;
5421 }
5422 
IsSessionVisibleForeground(const sptr<SceneSession> & session) const5423 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session) const
5424 {
5425     if (session == nullptr) {
5426         return false;
5427     }
5428     if (Session::IsScbCoreEnabled()) {
5429         return session->IsVisibleForeground();
5430     }
5431     return IsSessionVisible(session);
5432 }
5433 
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)5434 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
5435 {
5436     if (session == nullptr) {
5437         return;
5438     }
5439     int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
5440     WSRect rect = session->GetSessionRect();
5441     std::string sName;
5442     if (session->GetSessionInfo().isSystem_) {
5443         sName = session->GetSessionInfo().abilityName_;
5444     } else {
5445         sName = session->GetWindowName();
5446     }
5447     uint32_t flag = session->GetSessionProperty()->GetWindowFlags();
5448     uint64_t displayId = session->GetSessionProperty()->GetDisplayId();
5449     uint32_t orientation = 0;
5450     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
5451         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
5452     // std::setw is used to set the output width and different width values are set to keep the format aligned.
5453     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
5454         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
5455         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
5456         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
5457         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
5458         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
5459         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
5460         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
5461         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
5462         << "[ "
5463         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
5464         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
5465         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
5466         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
5467         << "]"
5468         << " [ "
5469         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
5470         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
5471         << "]"
5472         << " [ "
5473         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
5474         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
5475         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
5476         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
5477         << "]"
5478         << std::endl;
5479 }
5480 
DumpFocusInfo(std::ostringstream & oss)5481 void SceneSessionManager::DumpFocusInfo(std::ostringstream& oss)
5482 {
5483     auto defaultFocusedSessionId = windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID);
5484     oss << "Focus window: " << defaultFocusedSessionId << std::endl;
5485     std::vector<std::pair<DisplayId, int32_t>> allFocusedSessionList =
5486         windowFocusController_->GetAllFocusedSessionList();
5487     oss << "All Focus window: " << std::endl;
5488     if (allFocusedSessionList.size() > 0) {
5489         for (const auto& focusState : allFocusedSessionList) {
5490             oss << "DisplayId: " << focusState.first << " WindowId: " << focusState.second << std::endl;
5491         }
5492     }
5493 }
5494 
GetAllSessionDumpInfo(std::string & dumpInfo)5495 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
5496 {
5497     std::ostringstream oss;
5498     oss << "-------------------------------------ScreenGroup 0"
5499         << "-------------------------------------" << std::endl;
5500     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
5501         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]" << std::endl;
5502     std::vector<sptr<SceneSession>> allSession;
5503     std::vector<sptr<SceneSession>> backgroundSession;
5504     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
5505     {
5506         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5507         sceneSessionMapCopy = sceneSessionMap_;
5508     }
5509     for (const auto& elem : sceneSessionMapCopy) {
5510         auto curSession = elem.second;
5511         if (curSession == nullptr) {
5512             TLOGW(WmsLogTag::DEFAULT, "nullptr");
5513             continue;
5514         }
5515         if (!curSession->GetSessionInfo().isSystem_ &&
5516             (curSession->GetSessionState() < SessionState::STATE_FOREGROUND ||
5517             curSession->GetSessionState() > SessionState::STATE_BACKGROUND)) {
5518             TLOGW(WmsLogTag::DEFAULT, "id:%{public}d,invalid state:%{public}u",
5519                  curSession->GetPersistentId(), curSession->GetSessionState());
5520              continue;
5521          }
5522         if (IsSessionVisibleForeground(curSession)) {
5523             allSession.push_back(curSession);
5524         } else {
5525             backgroundSession.push_back(curSession);
5526         }
5527     }
5528     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
5529     uint32_t count = 0;
5530     for (const auto& session : allSession) {
5531         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
5532             oss << "---------------------------------------------------------------------------------------"
5533                 << std::endl;
5534         }
5535         DumpSessionInfo(session, oss);
5536         count++;
5537     }
5538     DumpFocusInfo(oss);
5539     oss << "SingleHand: X[" << singleHandTransform_.posX << "] Y[" << singleHandTransform_.posY << "] scale["
5540         << singleHandTransform_.scaleX << "]" << std::endl;
5541     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
5542     oss << "Highlighted windows: " << GetHighlightIdsStr() << std::endl;
5543     dumpInfo.append(oss.str());
5544     return WSError::WS_OK;
5545 }
5546 
GetAllSessionDumpDetailInfo(std::string & dumpInfo)5547 WSError SceneSessionManager::GetAllSessionDumpDetailInfo(std::string& dumpInfo)
5548 {
5549     std::ostringstream oss;
5550     std::vector<sptr<SceneSession>> allSession;
5551     std::vector<sptr<SceneSession>> backgroundSession;
5552 
5553     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
5554     {
5555         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5556         sceneSessionMapCopy = sceneSessionMap_;
5557     }
5558     for (const auto& elem : sceneSessionMapCopy) {
5559         auto curSession = elem.second;
5560         if (curSession == nullptr) {
5561             continue;
5562         }
5563         if (IsSessionVisibleForeground(curSession)) {
5564             allSession.push_back(curSession);
5565         } else {
5566             backgroundSession.push_back(curSession);
5567         }
5568     }
5569     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
5570     HidumpController::GetInstance().GetAllSessionDumpDetailedInfo(oss, allSession, backgroundSession);
5571     dumpInfo.append(oss.str());
5572     return WSError::WS_OK;
5573 }
5574 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)5575 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
5576 {
5577     dumpRootSceneFunc_ = func;
5578 }
5579 
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)5580 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
5581     const std::vector<std::string>& params, std::string& dumpInfo)
5582 {
5583     std::vector<std::string> resetParams;
5584     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
5585     if (resetParams.empty()) {
5586         TLOGND(WmsLogTag::DEFAULT, "do not dump ui info");
5587         return;
5588     }
5589 
5590     if (!session->GetSessionInfo().isSystem_) {
5591         TLOGD(WmsLogTag::DEFAULT, "Dump normal session, not system");
5592         dumpInfoFuture_.ResetLock({});
5593         session->DumpSessionElementInfo(resetParams);
5594         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
5595         for (auto& info: infos) {
5596             dumpInfo.append(info).append("\n");
5597         }
5598     } else {
5599         TLOGD(WmsLogTag::DEFAULT, "Dump system session");
5600         std::vector<std::string> infos;
5601         dumpRootSceneFunc_(resetParams, infos);
5602         for (auto& info: infos) {
5603             dumpInfo.append(info).append("\n");
5604         }
5605     }
5606 }
5607 
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)5608 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
5609     const std::string& strId)
5610 {
5611     uint64_t persistentId = std::stoull(strId);
5612     auto session = GetSceneSession(persistentId);
5613     if (session == nullptr) {
5614         return WSError::WS_ERROR_INVALID_PARAM;
5615     }
5616     auto sessionProperty = session->GetSessionProperty();
5617     WSRect rect = session->GetSessionRect();
5618     std::string isVisible = session->IsVisible() ? "true" : "false";
5619     std::string focusable = session->GetFocusable() ? "true" : "false";
5620     std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
5621     bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
5622     std::string isPrivacyMode = privacyMode ? "true" : "false";
5623     bool isFirstFrameAvailable = true;
5624     std::ostringstream oss;
5625     oss << "WindowName: " << session->GetWindowName()  << std::endl;
5626     oss << "DisplayId: " << 0 << std::endl;
5627     oss << "WinId: " << session->GetPersistentId() << std::endl;
5628     oss << "Pid: " << session->GetCallingPid() << std::endl;
5629     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
5630     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
5631     oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
5632     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
5633     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
5634     oss << "IsVisible: " << isVisible << std::endl;
5635     oss << "isRSVisible: " << (session->GetRSVisible() ? "true" : "false") << std::endl;
5636     oss << "Focusable: "  << focusable << std::endl;
5637     oss << "DecoStatus: "  << decoStatus << std::endl;
5638     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
5639     oss << "WindowRect: " << "[ "
5640         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
5641         << " ]" << std::endl;
5642     oss << "scaleX: " << session->GetScaleX() << std::endl;
5643     oss << "scaleY: " << session->GetScaleY() << std::endl;
5644     oss << "Offset: " << "[ "
5645         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
5646     oss << "Scale: " << "[ "
5647         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
5648         << session->GetPivotX() << ", " << session->GetPivotY()
5649         << " ]" << std::endl;
5650     oss << "ParentWindowId: " << session->GetParentPersistentId() << std::endl;
5651     dumpInfo.append(oss.str());
5652 
5653     DumpSessionElementInfo(session, params, dumpInfo);
5654     return WSError::WS_OK;
5655 }
5656 
GetSCBDebugDumpInfo(std::string && cmd,std::string & dumpInfo)5657 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)
5658 {
5659     // publish data
5660     bool ret = eventHandler_->PostSyncTask(
5661         [this, cmd = std::move(cmd)] { return scbDumpSubscriber_->Publish(cmd); }, "PublishSCBDumper");
5662     if (!ret) {
5663         return WSError::WS_ERROR_INVALID_OPERATION;
5664     }
5665     // get response event
5666     auto task = [this, &dumpInfo] {
5667         dumpInfo.append(scbDumpSubscriber_->GetDebugDumpInfo(WAIT_TIME));
5668         return WSError::WS_OK;
5669     };
5670     eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
5671     return WSError::WS_OK;
5672 }
5673 
NotifyDumpInfoResult(const std::vector<std::string> & info)5674 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
5675 {
5676     dumpInfoFuture_.SetValue(info);
5677     TLOGD(WmsLogTag::DEFAULT, "NotifyDumpInfoResult");
5678 }
5679 
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)5680 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
5681 {
5682     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
5683         TLOGE(WmsLogTag::DEFAULT, "GetSessionDumpInfo permission denied!");
5684         return WSError::WS_ERROR_INVALID_PERMISSION;
5685     }
5686 
5687     if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
5688         return GetAllSessionDumpInfo(dumpInfo);
5689     }
5690     if (params.size() == 1 && params[0] == ARG_DUMP_DETAIL) { // 1: params num
5691         return GetAllSessionDumpDetailInfo(dumpInfo);
5692     }
5693     if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
5694         return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
5695     }
5696     if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2: params num
5697         std::string cmd;
5698         std::for_each(params.begin() + 1, params.end(),
5699                         [&cmd](const std::string& value) {
5700                             cmd += value;
5701                             cmd += ' ';
5702                         });
5703         return GetSCBDebugDumpInfo(std::move(cmd), dumpInfo);
5704     }
5705     if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
5706         return GetTotalUITreeInfo(dumpInfo);
5707     }
5708     return WSError::WS_ERROR_INVALID_OPERATION;
5709 }
5710 
GetTotalUITreeInfo(std::string & dumpInfo)5711 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
5712 {
5713     TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
5714     if (dumpUITreeFunc_) {
5715         dumpUITreeFunc_(dumpInfo);
5716     } else {
5717         TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
5718     }
5719     return WSError::WS_OK;
5720 }
5721 
SetDumpUITreeFunc(const DumpUITreeFunc & func)5722 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
5723 {
5724     dumpUITreeFunc_ = func;
5725 }
5726 
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)5727 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
5728 {
5729     onFlushUIParamsFunc_ = std::move(func);
5730 }
5731 
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)5732 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
5733 {
5734     isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
5735 }
5736 
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)5737 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
5738 {
5739     taskScheduler_->PostAsyncTask([this, displayId, visible] {
5740         statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
5741         TLOGNI(WmsLogTag::WMS_IMMS, "set default visibility, "
5742             "display id %{public}" PRIu64 " visible %{public}d", displayId, visible);
5743     }, __func__);
5744 }
5745 
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)5746 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
5747 {
5748     return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
5749            statusBarDefaultVisibilityPerDisplay_[displayId] : true;
5750 }
5751 
FocusIDChange(int32_t persistentId,const sptr<SceneSession> & sceneSession)5752 void FocusIDChange(int32_t persistentId, const sptr<SceneSession>& sceneSession)
5753 {
5754     // notify RS
5755     TLOGD(WmsLogTag::WMS_FOCUS, "current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s, "
5756         "abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
5757         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
5758         sceneSession->GetSessionInfo().bundleName_.c_str(),
5759         sceneSession->GetSessionInfo().abilityName_.c_str(),
5760         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
5761     uint64_t focusNodeId = 0; // 0 means invalid
5762     if (sceneSession->GetSurfaceNode() == nullptr) {
5763         TLOGW(WmsLogTag::WMS_FOCUS, "focused window surfaceNode is null");
5764     } else {
5765         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
5766     }
5767     FocusAppInfo appInfo = {
5768         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
5769         sceneSession->GetSessionInfo().bundleName_,
5770         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
5771     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
5772 }
5773 
5774 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)5775 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
5776 {
5777     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
5778     {
5779         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5780         for (auto& iter : sceneSessionMap_) {
5781             ret.push_back(iter);
5782         }
5783     }
5784     std::sort(ret.begin(), ret.end(), cmp);
5785     return ret;
5786 }
5787 
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)5788 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
5789 {
5790     if (isFromTopToBottom) {
5791         TraverseSessionTreeFromTopToBottom(func);
5792     } else {
5793         TraverseSessionTreeFromBottomToTop(func);
5794     }
5795     return;
5796 }
5797 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)5798 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
5799 {
5800     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
5801         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
5802         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
5803         return lhsZOrder < rhsZOrder;
5804     };
5805     auto sceneSessionVector = GetSceneSessionVector(cmp);
5806 
5807     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
5808         auto session = iter->second;
5809         if (session == nullptr) {
5810             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5811             continue;
5812         }
5813         if (func(session)) {
5814             return;
5815         }
5816     }
5817     return;
5818 }
5819 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)5820 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
5821 {
5822     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5823     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
5824         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
5825         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
5826         return lhsZOrder < rhsZOrder;
5827     };
5828     auto sceneSessionVector = GetSceneSessionVector(cmp);
5829     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
5830     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
5831         auto session = iter->second;
5832         if (session == nullptr) {
5833             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5834             continue;
5835         }
5836         if (func(session)) {
5837             return;
5838         }
5839     }
5840     return;
5841 }
5842 
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5843 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
5844     FocusChangeReason reason)
5845 {
5846     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5847     auto sceneSession = GetSceneSession(persistentId);
5848     if (sceneSession == nullptr) {
5849         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5850         return WMError::WM_ERROR_NULLPTR;
5851     }
5852     int32_t callingPid = IPCSkeleton::GetCallingPid();
5853     if (callingPid != sceneSession->GetCallingPid() &&
5854         !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
5855         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
5856         return WMError::WM_ERROR_INVALID_CALLING;
5857     }
5858     auto task = [this, persistentId, isFocused, byForeground, reason]() {
5859         if (isFocused) {
5860             RequestSessionFocus(persistentId, byForeground, reason);
5861         } else {
5862             RequestSessionUnfocus(persistentId, reason);
5863         }
5864     };
5865     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
5866     focusChangeReason_ = reason;
5867     return WMError::WM_OK;
5868 }
5869 
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5870 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
5871     FocusChangeReason reason)
5872 {
5873     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5874     auto task = [this, persistentId, isFocused, byForeground, reason]() {
5875         if (isFocused) {
5876             if (reason == FocusChangeReason::FOREGROUND) {
5877                 RequestSessionFocusImmediately(persistentId);
5878                 return;
5879             }
5880             if (reason == FocusChangeReason::MOVE_UP) {
5881                 auto session = GetSceneSession(persistentId);
5882                 if (session && !session->IsFocused()) {
5883                     PostProcessFocusState state = { true, true, byForeground, reason };
5884                     session->SetPostProcessFocusState(state);
5885                 }
5886                 return;
5887             }
5888             // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
5889             if (reason == FocusChangeReason::CLICK) {
5890                 return;
5891             }
5892             if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
5893                 auto session = GetSceneSession(persistentId);
5894                 if (session && !session->IsFocused()) {
5895                     PostProcessFocusState state = { true, true, byForeground, reason };
5896                     session->SetPostProcessFocusState(state);
5897                 }
5898             }
5899         } else {
5900             RequestSessionUnfocus(persistentId, reason);
5901         }
5902     };
5903     taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
5904     return WMError::WM_OK;
5905 }
5906 
RequestFocusStatusBySA(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5907 WMError SceneSessionManager::RequestFocusStatusBySA(int32_t persistentId, bool isFocused,
5908     bool byForeground, FocusChangeReason reason)
5909 {
5910     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5911     if (!SessionPermission::IsSACalling()) {
5912         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, only support SA calling.");
5913         return WMError::WM_ERROR_INVALID_PERMISSION;
5914     }
5915     auto sceneSession = GetSceneSession(persistentId);
5916     if (sceneSession == nullptr) {
5917         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5918         return WMError::WM_ERROR_NULLPTR;
5919     }
5920     auto task = [this, persistentId, isFocused, byForeground, reason]() {
5921         if (isFocused) {
5922             RequestSessionFocus(persistentId, byForeground, reason);
5923         } else {
5924             RequestSessionUnfocus(persistentId, reason);
5925         }
5926     };
5927     taskScheduler_->PostAsyncTask(task, "RequestFocusOnPreviousWindow" + std::to_string(persistentId));
5928     return WMError::WM_OK;
5929 }
5930 
RequestAllAppSessionUnfocus()5931 void SceneSessionManager::RequestAllAppSessionUnfocus()
5932 {
5933     auto task = [this]() {
5934         RequestAllAppSessionUnfocusInner();
5935     };
5936     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
5937     return;
5938 }
5939 
5940 /**
5941  * request focus and ignore its state
5942  * only used when app main window start before foreground
5943  */
RequestSessionFocusImmediately(int32_t persistentId,bool blockNotifyUntilVisible)5944 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId, bool blockNotifyUntilVisible)
5945 {
5946     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, blockNotify: %{public}d", persistentId, blockNotifyUntilVisible);
5947     auto sceneSession = GetSceneSession(persistentId);
5948     if (sceneSession == nullptr) {
5949         TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
5950         return WSError::WS_ERROR_INVALID_SESSION;
5951     }
5952     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
5953     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
5954     if (focusGroup == nullptr) {
5955         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
5956         return WSError::WS_ERROR_NULLPTR;
5957     }
5958     // base block
5959     WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
5960     if (basicCheckRet != WSError::WS_OK) {
5961         return basicCheckRet;
5962     }
5963     if (!sceneSession->CheckFocusable()) {
5964         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
5965         return WSError::WS_DO_NOTHING;
5966     }
5967     if (!sceneSession->IsFocusedOnShow()) {
5968         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
5969         return WSError::WS_DO_NOTHING;
5970     }
5971 
5972     // specific block
5973     FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
5974     WSError specificCheckRet = RequestFocusSpecificCheck(displayId, sceneSession, true, reason);
5975     if (specificCheckRet != WSError::WS_OK) {
5976         return specificCheckRet;
5977     }
5978     auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
5979     focusGroup->SetNeedBlockNotifyUnfocusStatus(needBlockNotifyFocusStatusUntilForeground);
5980     if (!sceneSession->GetSessionInfo().isSystem_ && !blockNotifyUntilVisible && systemConfig_.IsPcWindow()) {
5981         if (!sceneSession->IsSessionForeground()) {
5982             focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
5983         }
5984     } else if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
5985         focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
5986     }
5987     ShiftFocus(displayId, sceneSession, false, reason);
5988     return WSError::WS_OK;
5989 }
5990 
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)5991 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
5992 {
5993     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
5994         persistentId, byForeground, reason);
5995     auto sceneSession = GetSceneSession(persistentId);
5996     if (sceneSession == nullptr) {
5997         TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
5998         return WSError::WS_ERROR_INVALID_SESSION;
5999     }
6000     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
6001     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6002     if (focusGroup == nullptr) {
6003         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6004         return WSError::WS_ERROR_NULLPTR;
6005     }
6006     WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
6007     if (basicCheckRet != WSError::WS_OK) {
6008         return basicCheckRet;
6009     }
6010     if (!sceneSession->CheckFocusable() || !IsSessionVisibleForeground(sceneSession)) {
6011         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
6012         return WSError::WS_DO_NOTHING;
6013     }
6014     if (!sceneSession->IsFocusedOnShow()) {
6015         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
6016         return WSError::WS_DO_NOTHING;
6017     }
6018     if (!sceneSession->IsFocusableOnShow() &&
6019         (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
6020         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
6021         return WSError::WS_DO_NOTHING;
6022     }
6023 
6024     // subwindow/dialog state block
6025     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
6026         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
6027         GetSceneSession(sceneSession->GetParentPersistentId()) &&
6028         !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
6029             TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
6030                 sceneSession->GetParentPersistentId());
6031             return WSError::WS_DO_NOTHING;
6032     }
6033     // specific block
6034     WSError specificCheckRet = RequestFocusSpecificCheck(displayId, sceneSession, byForeground, reason);
6035     if (specificCheckRet != WSError::WS_OK) {
6036         return specificCheckRet;
6037     }
6038     focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
6039     focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
6040     ShiftFocus(displayId, sceneSession, false, reason);
6041     return WSError::WS_OK;
6042 }
6043 
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)6044 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
6045 {
6046     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
6047     if (persistentId == INVALID_SESSION_ID) {
6048         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid: %{public}d", persistentId);
6049         return WSError::WS_ERROR_INVALID_SESSION;
6050     }
6051     auto sceneSession = GetSceneSession(persistentId);
6052     if (sceneSession == nullptr) {
6053         TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr: %{public}d", persistentId);
6054         return WSError::WS_ERROR_INVALID_SESSION;
6055     }
6056     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
6057     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6058     if (focusGroup == nullptr) {
6059         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6060         return WSError::WS_ERROR_NULLPTR;
6061     }
6062     auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
6063     if (persistentId != focusGroup->GetFocusedSessionId() &&
6064         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
6065         TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
6066         return WSError::WS_DO_NOTHING;
6067     }
6068     // if pop menu created by desktop request unfocus, back to desktop
6069     auto lastSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6070     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
6071         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
6072         RequestSessionFocus(focusGroup->GetLastFocusedSessionId(), false) == WSError::WS_OK) {
6073             TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
6074             return WSError::WS_OK;
6075     }
6076     auto nextSession = GetNextFocusableSession(displayId, persistentId);
6077     if (nextSession == nullptr) {
6078         DumpAllSessionFocusableInfo(persistentId);
6079     }
6080     focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
6081     focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
6082 
6083     if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
6084         return WSError::WS_OK;
6085     }
6086     if (nextSession && !nextSession->IsSessionForeground() && !nextSession->GetSessionInfo().isSystem_) {
6087         focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
6088     }
6089     return ShiftFocus(displayId, nextSession, true, reason);
6090 }
6091 
RequestAllAppSessionUnfocusInner()6092 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
6093 {
6094     TLOGI(WmsLogTag::WMS_FOCUS, "in");
6095     auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
6096     if (focusGroup == nullptr) {
6097         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
6098         return WSError::WS_ERROR_NULLPTR;
6099     }
6100     auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
6101     if (!focusedSession) {
6102         TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
6103         return WSError::WS_DO_NOTHING;
6104     }
6105     if (!focusedSession->IsAppSession()) {
6106         TLOGW(WmsLogTag::WMS_FOCUS, "Focused session is non app: %{public}d", focusGroup->GetFocusedSessionId());
6107         return WSError::WS_DO_NOTHING;
6108     }
6109     auto nextSession = GetTopFocusableNonAppSession();
6110 
6111     focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
6112     focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
6113     return ShiftFocus(DEFAULT_DISPLAY_ID, nextSession, true, FocusChangeReason::WIND);
6114 }
6115 
RequestFocusBasicCheck(int32_t persistentId,const sptr<FocusGroup> & focusGroup)6116 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId, const sptr<FocusGroup>& focusGroup)
6117 {
6118     // basic focus rule
6119     if (persistentId == INVALID_SESSION_ID) {
6120         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
6121         return WSError::WS_ERROR_INVALID_SESSION;
6122     }
6123     if (focusGroup == nullptr) {
6124         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
6125         return WSError::WS_ERROR_NULLPTR;
6126     }
6127     if (persistentId == focusGroup->GetFocusedSessionId()) {
6128         TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
6129         return WSError::WS_DO_NOTHING;
6130     }
6131     return WSError::WS_OK;
6132 }
6133 
6134 /**
6135  * @note @window.focus
6136  * When high zOrder System Session unfocus, check if the last focused app window can focus.
6137  */
CheckLastFocusedAppSessionFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & nextSession)6138 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(const sptr<SceneSession>& focusedSession,
6139     const sptr<SceneSession>& nextSession)
6140 {
6141     if (focusedSession == nullptr || nextSession == nullptr) {
6142         return false;
6143     }
6144     auto displayId = focusedSession->GetSessionProperty()->GetDisplayId();
6145     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6146     if (focusGroup == nullptr) {
6147         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6148         return false;
6149     }
6150     auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
6151     TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
6152         lastFocusedAppSessionId, nextSession->GetPersistentId());
6153 
6154     if (lastFocusedAppSessionId == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId) {
6155         return false;
6156     }
6157 
6158     if (!focusedSession->IsSystemSessionAboveApp()) {
6159         return false;
6160     }
6161 
6162     auto mode = nextSession->GetWindowMode();
6163     // only when next session is app, and in split or floation
6164     if (nextSession->IsAppSession() &&
6165         (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
6166          mode == WindowMode::WINDOW_MODE_FLOATING)) {
6167         if (RequestSessionFocus(lastFocusedAppSessionId, false, FocusChangeReason::LAST_FOCUSED_APP) ==
6168             WSError::WS_OK) {
6169             return true;
6170         }
6171         focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
6172     }
6173     return false;
6174 }
6175 
6176 /**
6177  * When switching focus, check if the blockingType window has been  traversed downwards.
6178  *
6179  * @return true: traversed downwards, false: not.
6180  */
CheckFocusIsDownThroughBlockingType(const sptr<SceneSession> & requestSceneSession,const sptr<SceneSession> & focusedSession,bool includingAppSession)6181 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(const sptr<SceneSession>& requestSceneSession,
6182     const sptr<SceneSession>& focusedSession, bool includingAppSession)
6183 {
6184     uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
6185     uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
6186     auto displayId = requestSceneSession->GetSessionProperty()->GetDisplayId();
6187     TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
6188         requestSessionZOrder, focusedSessionZOrder);
6189     if  (requestSessionZOrder < focusedSessionZOrder)  {
6190         auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(displayId, requestSessionZOrder,
6191             includingAppSession);
6192         uint32_t topNearestBlockingZOrder = 0;
6193         if  (topNearestBlockingFocusSession)  {
6194             topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
6195             TLOGD(WmsLogTag::WMS_FOCUS,  "requestSessionZOrder: %{public}d, focusedSessionZOrder:  %{public}d\
6196                 topNearestBlockingZOrder:  %{public}d",  requestSessionZOrder,  focusedSessionZOrder,
6197                 topNearestBlockingZOrder);
6198         }
6199         if  (focusedSessionZOrder >=  topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder)  {
6200             TLOGD(WmsLogTag::WMS_FOCUS,  "focus pass through, needs to be intercepted");
6201             return true;
6202         }
6203     }
6204     TLOGD(WmsLogTag::WMS_FOCUS, "not through");
6205     return false;
6206 }
6207 
CheckTopmostWindowFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession)6208 bool SceneSessionManager::CheckTopmostWindowFocus(const sptr<SceneSession>& focusedSession,
6209     const sptr<SceneSession>& sceneSession)
6210 {
6211     bool isFocusedMainSessionTopmost =
6212         focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
6213     auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
6214     bool isFocusedSessionParentTopmost = parentSession &&
6215         parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
6216     if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
6217         (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
6218         return true;
6219     }
6220     return false;
6221 }
6222 
CheckRequestFocusImmdediately(const sptr<SceneSession> & sceneSession)6223 bool SceneSessionManager::CheckRequestFocusImmdediately(const sptr<SceneSession>& sceneSession)
6224 {
6225     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
6226          (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
6227         (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
6228          ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
6229         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
6230         return true;
6231     }
6232     return false;
6233 }
6234 
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)6235 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
6236     const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
6237 {
6238     if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
6239         focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
6240         return false;
6241     }
6242     if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
6243         return false;
6244     }
6245     return sceneSession->GetZOrder() < focusedSession->GetZOrder();
6246 }
6247 
RequestFocusSpecificCheck(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)6248 WSError SceneSessionManager::RequestFocusSpecificCheck(DisplayId displayId, const sptr<SceneSession>& sceneSession,
6249     bool byForeground, FocusChangeReason reason)
6250 {
6251     TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
6252     int32_t persistentId = sceneSession->GetPersistentId();
6253     if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
6254         TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
6255         return WSError::WS_ERROR_INVALID_OPERATION;
6256     }
6257     // dialog get focus
6258     if (CheckRequestFocusImmdediately(sceneSession)) {
6259         return WSError::WS_DO_NOTHING;
6260     }
6261     // blocking-type session will block lower zOrder request focus
6262     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
6263     auto focusedSession = GetSceneSession(focusedSessionId);
6264     if (focusedSession) {
6265         TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d",  reason,
6266             byForeground);
6267         if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
6268             // return ok if focused session is topmost
6269             return WSError::WS_OK;
6270         }
6271         if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
6272             sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
6273             TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
6274             byForeground = false;
6275         }
6276         if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession,  focusedSession,  true))  {
6277             TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
6278             return WSError::WS_DO_NOTHING;
6279         }
6280         if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
6281             !byForeground)  {
6282             if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
6283                 && focusedSession->IsAppSession()) {
6284                 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
6285                 return WSError::WS_OK;
6286             }
6287         }
6288         bool isBlockingType = focusedSession->IsAppSession() ||
6289             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
6290         // temp check
6291         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
6292             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
6293                 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
6294                     persistentId);
6295                 return WSError::WS_DO_NOTHING;
6296         }
6297         // desktop click temp check
6298         if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
6299             TLOGD(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
6300             return WSError::WS_DO_NOTHING;
6301         }
6302     }
6303     return WSError::WS_OK;
6304 }
6305 
IsParentSessionVisible(const sptr<SceneSession> & session)6306 bool SceneSessionManager::IsParentSessionVisible(const sptr<SceneSession>& session)
6307 {
6308     if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
6309         session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
6310         auto parentSession = GetSceneSession(session->GetParentPersistentId());
6311         return parentSession == nullptr || IsSessionVisibleForeground(parentSession);
6312     }
6313     return true;
6314 }
6315 
DumpAllSessionFocusableInfo(int32_t persistentId)6316 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
6317 {
6318     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
6319     auto func = [this](const sptr<SceneSession>& session) {
6320         if (session == nullptr) {
6321             return false;
6322         }
6323         bool parentVisible = IsParentSessionVisible(session);
6324         bool sessionVisible = IsSessionVisible(session);
6325         TLOGNI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
6326             "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
6327             session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
6328             session->GetFocusable(), sessionVisible, parentVisible);
6329         return false;
6330     };
6331     TraverseSessionTree(func, true);
6332 }
6333 
GetNextFocusableSession(DisplayId displayId,int32_t persistentId)6334 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(DisplayId displayId, int32_t persistentId)
6335 {
6336     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
6337     bool previousFocusedSessionFound = false;
6338     sptr<SceneSession> ret = nullptr;
6339     DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
6340     auto func = [this, persistentId, &previousFocusedSessionFound, &ret, displayGroupId](sptr<SceneSession> session) {
6341         if (session == nullptr) {
6342             return false;
6343         }
6344         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
6345             displayGroupId) {
6346             return false;
6347         }
6348         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
6349             TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
6350             return false;
6351         }
6352         if (previousFocusedSessionFound && session->CheckFocusable() &&
6353             session->IsVisible() && IsParentSessionVisible(session)) {
6354             ret = session;
6355             return true;
6356         }
6357         if (session->GetPersistentId() == persistentId) {
6358             previousFocusedSessionFound = true;
6359         }
6360         return false;
6361     };
6362     TraverseSessionTree(func, true);
6363     return ret;
6364 }
6365 
6366 /**
6367  * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
6368  * and it is the closest;
6369  */
GetTopNearestBlockingFocusSession(DisplayId displayId,uint32_t zOrder,bool includingAppSession)6370 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(DisplayId displayId, uint32_t zOrder,
6371     bool includingAppSession)
6372 {
6373     sptr<SceneSession> ret = nullptr;
6374     DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
6375     auto func = [this, &ret, zOrder, includingAppSession, displayGroupId](sptr<SceneSession> session) {
6376         if (session == nullptr) {
6377             return false;
6378         }
6379         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
6380             displayGroupId) {
6381             return false;
6382         }
6383         uint32_t sessionZOrder = session->GetZOrder();
6384         if (sessionZOrder <= zOrder) { // must be above the target session
6385             return false;
6386         }
6387         if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6388             TLOGND(WmsLogTag::WMS_FOCUS, "topmost window do not block");
6389             return false;
6390         }
6391         auto parentSession = GetSceneSession(session->GetParentPersistentId());
6392         if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
6393             parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
6394             parentSession->IsTopmost()) {
6395             TLOGND(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
6396             return false;
6397         }
6398         bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
6399         bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
6400                               (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
6401                               (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
6402         if (IsSessionVisibleForeground(session) && isBlockingType)  {
6403             ret = session;
6404             return true;
6405         }
6406         return false;
6407     };
6408     TraverseSessionTree(func, false);
6409     return ret;
6410 }
6411 
GetTopFocusableNonAppSession()6412 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
6413 {
6414     TLOGD(WmsLogTag::WMS_FOCUS, "in.");
6415     sptr<SceneSession> ret = nullptr;
6416     auto func = [this, &ret](sptr<SceneSession> session) {
6417         if (session == nullptr) {
6418             return false;
6419         }
6420         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
6421             DEFAULT_DISPLAY_ID) {
6422             return false;
6423         }
6424         if (session->IsAppSession()) {
6425             return true;
6426         }
6427         if (session->CheckFocusable() && IsSessionVisibleForeground(session)) {
6428             ret = session;
6429         }
6430         return false;
6431     };
6432     TraverseSessionTree(func, false);
6433     return ret;
6434 }
6435 
SetShiftFocusListener(const ProcessShiftFocusFunc & func)6436 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
6437 {
6438     TLOGD(WmsLogTag::WMS_FOCUS, "in");
6439     shiftFocusFunc_ = func;
6440 }
6441 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)6442 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
6443 {
6444     TLOGD(WmsLogTag::WMS_FOCUS, "in");
6445     notifySCBAfterFocusedFunc_ = func;
6446 }
6447 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)6448 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
6449 {
6450     TLOGD(WmsLogTag::WMS_FOCUS, "in");
6451     notifySCBAfterUnfocusedFunc_ = func;
6452 }
6453 
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)6454 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
6455 {
6456     TLOGD(WmsLogTag::DEFAULT, "in");
6457     callingSessionIdChangeFunc_ = func;
6458 }
6459 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)6460 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
6461 {
6462     TLOGD(WmsLogTag::DEFAULT, "in");
6463     startUIAbilityErrorFunc_ = func;
6464 }
6465 
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)6466 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
6467     const AbilityManagerCollaboratorRegisteredFunc& func)
6468 {
6469     auto task = [this, func] {
6470         abilityManagerCollaboratorRegisteredFunc_ = func;
6471     };
6472     taskScheduler_->PostAsyncTask(task, __func__);
6473 }
6474 
ShiftFocus(DisplayId displayId,const sptr<SceneSession> & nextSession,bool isProactiveUnfocus,FocusChangeReason reason)6475 WSError SceneSessionManager::ShiftFocus(DisplayId displayId, const sptr<SceneSession>& nextSession,
6476     bool isProactiveUnfocus, FocusChangeReason reason)
6477 {
6478     // unfocus
6479     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
6480     int32_t focusedId = focusedSessionId;
6481     auto focusedSession = GetSceneSession(focusedSessionId);
6482     UpdateFocusStatus(displayId, focusedSession, false);
6483     // focus
6484     int32_t nextId = INVALID_SESSION_ID;
6485     if (nextSession == nullptr) {
6486         std::string sessionLog(GetAllSessionFocusInfo());
6487         TLOGW(WmsLogTag::WMS_FOCUS, "next session nullptr! id: %{public}d, info: %{public}s",
6488             focusedSessionId, sessionLog.c_str());
6489     } else {
6490         nextId = nextSession->GetPersistentId();
6491     }
6492     UpdateFocusStatus(displayId, nextSession, true);
6493     UpdateHighlightStatus(displayId, focusedSession, nextSession, isProactiveUnfocus);
6494     if (shiftFocusFunc_ != nullptr) {
6495         shiftFocusFunc_(nextId, displayId);
6496     }
6497     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
6498     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
6499     if (!scbPrevFocus && scbCurrFocus) {
6500         if (notifySCBAfterFocusedFunc_ != nullptr) {
6501             notifySCBAfterFocusedFunc_();
6502         }
6503     } else if (scbPrevFocus && !scbCurrFocus) {
6504         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
6505             notifySCBAfterUnfocusedFunc_();
6506         }
6507     }
6508     TLOGI(WmsLogTag::WMS_FOCUS, "displayId: %{public}" PRIu64
6509         ", focusedId: %{public}d, nextId: %{public}d, reason: %{public}d", displayId, focusedId, nextId, reason);
6510     return WSError::WS_OK;
6511 }
6512 
UpdateFocusStatus(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool isFocused)6513 void SceneSessionManager::UpdateFocusStatus(DisplayId displayId, const sptr<SceneSession>& sceneSession,
6514     bool isFocused)
6515 {
6516     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6517     if (focusGroup == nullptr) {
6518         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6519         return;
6520     }
6521     bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
6522     bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
6523     if (sceneSession == nullptr) {
6524         TLOGW(WmsLogTag::WMS_FOCUS, "session is nullptr");
6525         if (isFocused) {
6526             SetFocusedSessionId(INVALID_SESSION_ID, displayId);
6527             focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
6528             auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6529             NotifyUnFocusedByMission(prevSession);
6530         }
6531         return;
6532     }
6533     TLOGD(WmsLogTag::WMS_FOCUS, "name: %{public}s, id: %{public}d, isFocused: %{public}d, displayId: %{public}" PRIu64,
6534           sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused, displayId);
6535     // set focused
6536     if (isFocused) {
6537         SetFocusedSessionId(sceneSession->GetPersistentId(), displayId);
6538         if (sceneSession->IsAppOrLowerSystemSession()) {
6539             focusGroup->SetLastFocusedAppSessionId(sceneSession->GetPersistentId());
6540         }
6541     }
6542     sceneSession->UpdateFocus(isFocused);
6543     // notify listenerController unfocused
6544     auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6545     if (isFocused && MissionChanged(prevSession, sceneSession)) {
6546         NotifyUnFocusedByMission(prevSession);
6547     }
6548     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground) || (!isFocused && !needBlockNotifyUnfocusStatus)) {
6549         NotifyFocusStatus(sceneSession, isFocused, focusGroup);
6550     }
6551 }
6552 
6553 /** @note @window.focus */
UpdateHighlightStatus(DisplayId displayId,const sptr<SceneSession> & preSceneSession,const sptr<SceneSession> & currSceneSession,bool isProactiveUnfocus)6554 void SceneSessionManager::UpdateHighlightStatus(DisplayId displayId, const sptr<SceneSession>& preSceneSession,
6555     const sptr<SceneSession>& currSceneSession, bool isProactiveUnfocus)
6556 {
6557     if (preSceneSession == nullptr || currSceneSession == nullptr) {
6558         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6559         return;
6560     }
6561     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6562     if (focusGroup == nullptr) {
6563         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6564         return;
6565     }
6566     bool needBlockHighlightNotify = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
6567     if(isProactiveUnfocus){
6568         TLOGD(WmsLogTag::WMS_FOCUS, "proactiveUnfocus");
6569         RemoveHighlightSessionIds(preSceneSession);
6570     }
6571     if(currSceneSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
6572         TLOGD(WmsLogTag::WMS_FOCUS, "exclusively highlighted");
6573         SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6574         return;
6575     }
6576     if(currSceneSession->GetSessionInfo().isSystem_) {
6577         TLOGD(WmsLogTag::WMS_FOCUS, "system highlighted");
6578         AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6579         return;
6580     }
6581     if(currSceneSession->IsSameMainSession(preSceneSession)) {
6582         TLOGD(WmsLogTag::WMS_FOCUS, "related highlighted");
6583         AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6584         return;
6585     }
6586     TLOGD(WmsLogTag::WMS_FOCUS, "highlighted");
6587     SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6588 }
6589 
6590 /** @note @window.focus */
SetHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)6591 void SceneSessionManager::SetHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
6592 {
6593     if (sceneSession == nullptr) {
6594         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6595         return;
6596     }
6597     {
6598         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6599         for (auto persistentId : highlightIds_) {
6600             auto session = GetSceneSession(persistentId);
6601             if (session == nullptr) {
6602                 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr");
6603                 continue;
6604             }
6605             if (sceneSession->GetPersistentId() != persistentId) {
6606                 session->UpdateHighlightStatus(false, false);
6607             }
6608         }
6609         sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
6610         highlightIds_.clear();
6611         highlightIds_.insert(sceneSession->GetPersistentId());
6612     }
6613     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
6614 }
6615 
6616 /** @note @window.focus */
AddHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)6617 void SceneSessionManager::AddHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
6618 {
6619     if (sceneSession == nullptr) {
6620         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6621         return;
6622     }
6623     sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
6624     {
6625         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6626         highlightIds_.insert(sceneSession->GetPersistentId());
6627     }
6628     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
6629 }
6630 
6631 /** @note @window.focus */
RemoveHighlightSessionIds(const sptr<SceneSession> & sceneSession)6632 void SceneSessionManager::RemoveHighlightSessionIds(const sptr<SceneSession>& sceneSession)
6633 {
6634     if (sceneSession == nullptr) {
6635         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6636         return;
6637     }
6638     {
6639         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6640         if (highlightIds_.find(sceneSession->GetPersistentId()) != highlightIds_.end()) {
6641             sceneSession->UpdateHighlightStatus(false, false);
6642             highlightIds_.erase(sceneSession->GetPersistentId());
6643         } else {
6644             TLOGE(WmsLogTag::WMS_FOCUS, "not found scene session with id: %{public}d", sceneSession->GetPersistentId());
6645         }
6646 
6647     }
6648     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
6649 }
6650 
6651 /** @note @window.focus */
GetHighlightIdsStr()6652 std::string SceneSessionManager::GetHighlightIdsStr()
6653 {
6654     std::ostringstream oss;
6655     {
6656         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6657         for (auto it = highlightIds_.begin(); it != highlightIds_.end(); it++) {
6658             oss << *it;
6659             if(std::next(it) != highlightIds_.end()) {
6660                 oss << ", ";
6661             }
6662         }
6663 
6664     }
6665     return oss.str();
6666 }
6667 
NotifyFocusStatus(const sptr<SceneSession> & sceneSession,bool isFocused,const sptr<FocusGroup> & focusGroup)6668 void SceneSessionManager::NotifyFocusStatus(const sptr<SceneSession>& sceneSession, bool isFocused,
6669     const sptr<FocusGroup>& focusGroup)
6670 {
6671     if (focusGroup == nullptr) {
6672         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
6673         return;
6674     }
6675     int32_t persistentId = sceneSession->GetPersistentId();
6676 
6677     TLOGI(WmsLogTag::WMS_FOCUS,
6678         "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
6679         sceneSession->GetSessionInfo().bundleName_.c_str(),
6680         sceneSession->GetSessionInfo().abilityName_.c_str(),
6681         sceneSession->GetWindowNameAllType().c_str(),
6682         persistentId, isFocused);
6683     if (isFocused) {
6684         if (IsSessionVisibleForeground(sceneSession)) {
6685             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
6686         }
6687         UpdateBrightness(focusGroup->GetFocusedSessionId());
6688         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
6689     }
6690     // notify window manager
6691     sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
6692         sceneSession->GetWindowId(),
6693         static_cast<DisplayId>(focusGroup->GetDisplayGroupId()),
6694         sceneSession->GetCallingPid(),
6695         sceneSession->GetCallingUid(),
6696         sceneSession->GetWindowType(),
6697         sceneSession->GetAbilityToken()
6698     );
6699     SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
6700     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
6701     sceneSession->NotifyFocusStatus(isFocused);
6702     // notify listenerController focused
6703     auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6704     if (isFocused && MissionChanged(prevSession, sceneSession)) {
6705         NotifyFocusedByMission(sceneSession);
6706     }
6707 }
6708 
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)6709 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
6710     const std::string& reason)
6711 {
6712     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
6713     nlohmann::json payload;
6714     payload.emplace("uid", uid);
6715     payload.emplace("bundleName", bundleName);
6716     payload.emplace("reason", reason);
6717     nlohmann::json reply;
6718     return ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
6719 }
6720 
NotifyFocusStatusByMission(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)6721 void SceneSessionManager::NotifyFocusStatusByMission(const sptr<SceneSession>& prevSession,
6722     const sptr<SceneSession>& currSession)
6723 {
6724     if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
6725         TLOGD(WmsLogTag::WMS_FOCUS, "Unfocused, id: %{public}d", prevSession->GetMissionId());
6726         listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
6727     }
6728     if (currSession && !currSession->GetSessionInfo().isSystem_) {
6729         TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", currSession->GetMissionId());
6730         listenerController_->NotifySessionFocused(currSession->GetMissionId());
6731     }
6732 }
6733 
NotifyUnFocusedByMission(const sptr<SceneSession> & sceneSession)6734 void SceneSessionManager::NotifyUnFocusedByMission(const sptr<SceneSession>& sceneSession)
6735 {
6736     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
6737         TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", sceneSession->GetMissionId());
6738         listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
6739     }
6740 }
6741 
NotifyFocusedByMission(const sptr<SceneSession> & sceneSession)6742 void SceneSessionManager::NotifyFocusedByMission(const sptr<SceneSession>& sceneSession)
6743 {
6744     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
6745         TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", sceneSession->GetMissionId());
6746         listenerController_->NotifySessionFocused(sceneSession->GetMissionId());
6747     }
6748 }
6749 
MissionChanged(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)6750 bool SceneSessionManager::MissionChanged(const sptr<SceneSession>& prevSession, const sptr<SceneSession>& currSession)
6751 {
6752     if (prevSession == nullptr && currSession == nullptr) {
6753         return false;
6754     }
6755     if (prevSession == nullptr || currSession == nullptr) {
6756         return true;
6757     }
6758     return prevSession->GetMissionId() != currSession->GetMissionId();
6759 }
6760 
GetAllSessionFocusInfo()6761 std::string SceneSessionManager::GetAllSessionFocusInfo()
6762 {
6763     std::ostringstream os;
6764     auto func = [&os](sptr<SceneSession> session) {
6765         if (session == nullptr) {
6766             TLOGNE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6767             return false;
6768         }
6769         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
6770               ", focusable: " << session->GetFocusable() << ";";
6771         return false;
6772     };
6773     TraverseSessionTree(func, true);
6774     return os.str();
6775 }
6776 
UpdateFocus(int32_t persistentId,bool isFocused)6777 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
6778 {
6779     auto task = [this, persistentId, isFocused]() {
6780         // notify session and client
6781         auto sceneSession = GetSceneSession(persistentId);
6782         if (sceneSession == nullptr) {
6783             TLOGNE(WmsLogTag::WMS_FOCUS, "UpdateFocus could not find window, persistentId:%{public}d", persistentId);
6784             return WSError::WS_ERROR_INVALID_WINDOW;
6785         }
6786         TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
6787             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
6788         // focusId change
6789         auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
6790         auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
6791         if (isFocused) {
6792             SetFocusedSessionId(displayId, persistentId);
6793             UpdateBrightness(focusedSessionId);
6794             FocusIDChange(persistentId, sceneSession);
6795         } else if (persistentId == GetFocusedSessionId()) {
6796             SetFocusedSessionId(displayId, INVALID_SESSION_ID);
6797         }
6798         // notify window manager
6799         sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
6800             sceneSession->GetWindowId(),
6801             static_cast<DisplayId>(0),
6802             sceneSession->GetCallingPid(),
6803             sceneSession->GetCallingUid(),
6804             sceneSession->GetWindowType(),
6805             sceneSession->GetAbilityToken()
6806         );
6807         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
6808         WSError res = WSError::WS_OK;
6809         res = sceneSession->UpdateFocus(isFocused);
6810         if (res != WSError::WS_OK) {
6811             return res;
6812         }
6813         TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6814               sceneSession->GetSessionInfo().isSystem_);
6815         if (!sceneSession->GetSessionInfo().isSystem_) {
6816             if (isFocused) {
6817                 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyFocused, id: %{public}d", sceneSession->GetPersistentId());
6818                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
6819             } else {
6820                 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyUnFocused, id: %{public}d", sceneSession->GetPersistentId());
6821                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
6822             }
6823         }
6824         return WSError::WS_OK;
6825     };
6826 
6827     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
6828     return WSError::WS_OK;
6829 }
6830 
UpdateWindowMode(int32_t persistentId,int32_t windowMode)6831 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
6832 {
6833     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, mode: %{public}d", persistentId, windowMode);
6834     auto sceneSession = GetSceneSession(persistentId);
6835     if (sceneSession == nullptr) {
6836         TLOGE(WmsLogTag::DEFAULT, "could not find window, Id:%{public}d", persistentId);
6837         return WSError::WS_ERROR_INVALID_WINDOW;
6838     }
6839     WindowMode mode = static_cast<WindowMode>(windowMode);
6840     return sceneSession->UpdateWindowMode(mode);
6841 }
6842 
GetNormalSingleHandTransform() const6843 SingleHandTransform SceneSessionManager::GetNormalSingleHandTransform() const
6844 {
6845     return singleHandTransform_;
6846 }
6847 
GetSingleHandScreenInfo() const6848 SingleHandScreenInfo SceneSessionManager::GetSingleHandScreenInfo() const
6849 {
6850     return singleHandScreenInfo_;
6851 }
6852 
GetOriginRect() const6853 WSRect SceneSessionManager::GetOriginRect() const
6854 {
6855     return originRect_;
6856 }
6857 
GetSingleHandRect() const6858 WSRect SceneSessionManager::GetSingleHandRect() const
6859 {
6860     return singleHandRect_;
6861 }
6862 
NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo,WSRect originRect,WSRect singleHandRect)6863 void SceneSessionManager::NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo, WSRect originRect, WSRect singleHandRect)
6864 {
6865     const char* const funcName = __func__;
6866     taskScheduler_->PostAsyncTask([this, singleHandScreenInfo, originRect, singleHandRect, funcName] {
6867         if (!systemConfig_.IsPhoneWindow()) {
6868             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: only support phone", funcName);
6869             return;
6870         }
6871         int32_t displayWidth = 0;
6872         int32_t displayHeight = 0;
6873         ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6874         if (!GetDisplaySizeById(defaultScreenId, displayWidth, displayHeight)) {
6875             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: get display size failed", funcName);
6876             return;
6877         }
6878         singleHandScreenInfo_ = singleHandScreenInfo;
6879         originRect_ = originRect;
6880         singleHandRect_ = singleHandRect;
6881         singleHandTransform_.posX = singleHandRect.posX_;
6882         singleHandTransform_.posY = singleHandRect.posY_;
6883         singleHandTransform_.scaleX = static_cast<float>(singleHandScreenInfo_.scaleRatio) / 100;
6884         singleHandTransform_.scaleY = singleHandTransform_.scaleX;
6885         {
6886             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6887             for (const auto& [_, sceneSession] : sceneSessionMap_) {
6888                 if (sceneSession == nullptr || !IsInDefaultScreen(sceneSession) ||
6889                     sceneSession->GetWindowName().find("OneHandModeBackground", 0) != std::string::npos) {
6890                     continue;
6891                 }
6892                 sceneSession->SetSingleHandModeFlag(true);
6893                 sceneSession->SetSingleHandTransform(singleHandTransform_);
6894                 sceneSession->NotifySingleHandTransformChange(singleHandTransform_);
6895             }
6896         }
6897         FlushWindowInfoToMMI();
6898     }, funcName);
6899 }
6900 
RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc && func)6901 void SceneSessionManager::RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc&& func)
6902 {
6903     getRSNodeByStringIDFunc_ = std::move(func);
6904 }
6905 
RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc && func)6906 void SceneSessionManager::RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc&& func)
6907 {
6908     setTopWindowBoundaryByIDFunc_ = std::move(func);
6909 }
6910 
RegisterSingleHandContainerNode(const std::string & stringId)6911 void SceneSessionManager::RegisterSingleHandContainerNode(const std::string& stringId)
6912 {
6913     if (getRSNodeByStringIDFunc_ == nullptr) {
6914         TLOGE(WmsLogTag::WMS_LAYOUT, "func is nullptr");
6915         return;
6916     }
6917     auto rsNode = getRSNodeByStringIDFunc_(stringId);
6918     if (rsNode == nullptr) {
6919         TLOGE(WmsLogTag::WMS_LAYOUT, "node is nullptr");
6920         return;
6921     }
6922     TLOGI(WmsLogTag::WMS_LAYOUT, "get OneHandModeBox node, id: %{public}" PRIu64, rsNode->GetId());
6923     setTopWindowBoundaryByIDFunc_(stringId);
6924     rsInterface_.SetWindowContainer(rsNode->GetId(), true);
6925 }
6926 
GetSingleHandCompatibleModeConfig() const6927 const SingleHandCompatibleModeConfig& SceneSessionManager::GetSingleHandCompatibleModeConfig() const
6928 {
6929     return singleHandCompatibleModeConfig_;
6930 }
6931 
6932 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6933 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6934     MMI::PointerEvent::PointerItem& pointerItem)
6935 {
6936     struct PointerEventData {
6937         double x;
6938         double y;
6939         uint64_t time;
6940     } pointerEventData = {
6941         .x = pointerItem.GetDisplayX(),
6942         .y = pointerItem.GetDisplayY(),
6943         .time = pointerEvent->GetActionTime()
6944     };
6945 
6946     const uint32_t MAX_HMAC_SIZE = 64;
6947     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
6948     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
6949     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
6950     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
6951         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
6952         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
6953     }
6954 }
6955 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
6956 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)6957 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
6958 {
6959     if (!pointerEvent) {
6960         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null");
6961         return WSError::WS_ERROR_NULLPTR;
6962     }
6963     MMI::PointerEvent::PointerItem pointerItem;
6964     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
6965         TLOGE(WmsLogTag::WMS_EVENT, "Failed to get pointerItem");
6966         return WSError::WS_ERROR_INVALID_PARAM;
6967     }
6968 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
6969     FillSecCompEnhanceData(pointerEvent, pointerItem);
6970 #endif
6971     TLOGI(WmsLogTag::WMS_EVENT, "eid=%{public}d,ac=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
6972         pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
6973     pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
6974     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
6975     return WSError::WS_OK;
6976 }
6977 
SetScreenLocked(const bool isScreenLocked)6978 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
6979 {
6980     taskScheduler_->PostTask([this, isScreenLocked] {
6981         isScreenLocked_ = isScreenLocked;
6982         DeleteStateDetectTask();
6983         NotifyPiPWindowVisibleChange(isScreenLocked);
6984     }, __func__);
6985 }
6986 
SetUserAuthPassed(bool isUserAuthPassed)6987 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
6988 {
6989     taskScheduler_->PostTask([this, isUserAuthPassed] {
6990         isUserAuthPassed_ = isUserAuthPassed;
6991     }, __func__);
6992 }
6993 
DeleteStateDetectTask()6994 void SceneSessionManager::DeleteStateDetectTask()
6995 {
6996     if (!IsScreenLocked()) {
6997         return;
6998     }
6999     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7000     for (auto iter : sceneSessionMap_) {
7001         auto& session = iter.second;
7002         if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
7003             taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
7004             DetectTaskInfo detectTaskInfo;
7005             session->SetDetectTaskInfo(detectTaskInfo);
7006         }
7007     }
7008 }
7009 
IsScreenLocked() const7010 bool SceneSessionManager::IsScreenLocked() const
7011 {
7012     return isScreenLocked_;
7013 }
7014 
IsUserAuthPassed() const7015 bool SceneSessionManager::IsUserAuthPassed() const
7016 {
7017     return isUserAuthPassed_;
7018 }
7019 
RegisterWindowChanged(const WindowChangedFunc & func)7020 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
7021 {
7022     WindowChangedFunc_ = func;
7023 }
7024 
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)7025 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
7026     const std::unordered_set<std::string>& privacyBundles)
7027 {
7028     bool needNotify = false;
7029     static int reSendTimes = MAX_RESEND_TIMES;
7030     std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
7031     do {
7032         if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
7033             TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
7034             needNotify = !privacyBundles.empty();
7035             break;
7036         }
7037         const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
7038         if (lastPrivacyBundles.size() != privacyBundles.size()) {
7039             TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
7040                   lastPrivacyBundles.size(), privacyBundles.size());
7041             needNotify = true;
7042             break;
7043         }
7044         for (const auto& bundle : lastPrivacyBundles) {
7045             if (privacyBundles.find(bundle) == privacyBundles.end()) {
7046                 needNotify = true;
7047                 break;
7048             }
7049         }
7050     } while (false);
7051 
7052     TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
7053           displayId, needNotify);
7054     if (needNotify) {
7055         reSendTimes = MAX_RESEND_TIMES;
7056         privacyBundleMap_[displayId] = privacyBundles;
7057     } else if (reSendTimes > 0) {
7058         needNotify = true;
7059         reSendTimes--;
7060         privacyBundleMap_[displayId] = privacyBundles;
7061     }
7062     return needNotify;
7063 }
7064 
UpdatePrivateStateAndNotify(uint32_t persistentId)7065 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
7066 {
7067     auto sceneSession = GetSceneSession(persistentId);
7068     if (sceneSession == nullptr) {
7069         TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid=%{public}u.", persistentId);
7070         return;
7071     }
7072 
7073     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7074     std::unordered_set<std::string> privacyBundleList;
7075     GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
7076     if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
7077         return;
7078     }
7079 
7080     std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
7081     ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
7082         !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
7083     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
7084     if (!bundleListForNotify.empty()) {
7085         TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
7086     }
7087     for (const auto& bundle : bundleListForNotify) {
7088         TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display=%{public}" PRIu64 ", bundle=%{public}s.",
7089               displayId, bundle.c_str());
7090     }
7091 }
7092 
UpdatePrivateStateAndNotifyForAllScreens()7093 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
7094 {
7095     auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
7096     for (auto& iter : screenProperties) {
7097         auto displayId = iter.first;
7098         std::unordered_set<std::string> privacyBundleList;
7099         GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
7100 
7101         ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
7102             !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
7103     }
7104 }
7105 
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)7106 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
7107     std::unordered_set<std::string>& privacyBundles)
7108 {
7109     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7110     for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
7111         if (sceneSession == nullptr) {
7112             TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid=%{public}d.", persistentId);
7113             continue;
7114         }
7115         auto sessionProperty = sceneSession->GetSessionProperty();
7116         auto currentDisplayId = sessionProperty->GetDisplayId();
7117         if (displayId != currentDisplayId) {
7118             continue;
7119         }
7120         bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
7121                             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
7122         if (isForeground && sceneSession->GetParentSession() != nullptr) {
7123             isForeground = isForeground &&
7124                 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
7125                  sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
7126         }
7127         bool isPrivate = sessionProperty->GetPrivacyMode() ||
7128             sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
7129         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
7130         if ((isForeground || IsSystemWindowVisible) && isPrivate) {
7131             if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
7132                 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
7133             } else {
7134                 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "bundle name is empty, wid=%{public}d.", persistentId);
7135                 privacyBundles.insert(sceneSession->GetWindowName());
7136             }
7137         }
7138     }
7139 }
7140 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)7141 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
7142 {
7143     if (sceneSession == nullptr) {
7144         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7145         return;
7146     }
7147     sceneSession->SetSessionStateChangeNotifyManagerListener(
7148         [this](int32_t persistentId, const SessionState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
7149             OnSessionStateChange(persistentId, state);
7150         });
7151     TLOGD(WmsLogTag::DEFAULT, "success");
7152 }
7153 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)7154 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
7155 {
7156     if (sceneSession == nullptr) {
7157         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7158         return;
7159     }
7160     sceneSession->SetSessionInfoChangeNotifyManagerListener([this](int32_t persistentId) {
7161         NotifyWindowInfoChangeFromSession(persistentId);
7162     });
7163 }
7164 
RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession> & sceneSession)7165 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
7166 {
7167     if (sceneSession == nullptr) {
7168         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7169         return;
7170     }
7171     sceneSession->SetRequestFocusStatusNotifyManagerListener(
7172         [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
7173             RequestFocusStatus(persistentId, isFocused, byForeground, reason);
7174         });
7175     TLOGD(WmsLogTag::DEFAULT, "success");
7176 }
7177 
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)7178 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
7179 {
7180     GetStateFromManagerFunc func = [this](const ManagerState key) {
7181         switch (key) {
7182             case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
7183                 return this->IsScreenLocked();
7184                 break;
7185             default:
7186                 return false;
7187                 break;
7188         }
7189     };
7190     if (sceneSession == nullptr) {
7191         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7192         return;
7193     }
7194     sceneSession->SetGetStateFromManagerListener(func);
7195     TLOGD(WmsLogTag::DEFAULT, "success");
7196 }
7197 
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)7198 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
7199 {
7200     SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
7201         const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
7202         if (sceneSession == nullptr || property == nullptr) {
7203             TLOGNE(WmsLogTag::DEFAULT, "params is nullptr");
7204             return;
7205         }
7206         switch (action) {
7207             case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
7208                 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7209                                    sceneSession->keepScreenLock_);
7210                 break;
7211             case WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON:
7212                 HandleKeepScreenOn(sceneSession, property->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7213                                    sceneSession->viewKeepScreenLock_);
7214                 break;
7215             case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
7216             case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
7217             case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
7218             case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
7219             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
7220             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
7221                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7222                 break;
7223             case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
7224                 SetBrightness(sceneSession, property->GetBrightness());
7225                 break;
7226             case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
7227             case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
7228                 UpdatePrivateStateAndNotify(property->GetPersistentId());
7229                 break;
7230             case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
7231                 CheckAndNotifyWaterMarkChangedResult();
7232                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7233                 break;
7234             case WSPropertyChangeAction::ACTION_UPDATE_MODE:
7235                 ProcessWindowModeType();
7236                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7237                 break;
7238             case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
7239                 HandleHideNonSystemFloatingWindows(property, sceneSession);
7240                 break;
7241             case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
7242                 FlushWindowInfoToMMI();
7243                 break;
7244             default:
7245                 break;
7246         }
7247     };
7248     if (sceneSession != nullptr) {
7249         sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
7250     }
7251 }
7252 
OnSessionStateChange(int32_t persistentId,const SessionState & state)7253 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
7254     int32_t persistentId, const SessionState& state)
7255 {
7256     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
7257     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, state:%{public}u", persistentId, state);
7258     auto sceneSession = GetSceneSession(persistentId);
7259     if (sceneSession == nullptr) {
7260         TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
7261         return;
7262     }
7263     switch (state) {
7264         case SessionState::STATE_FOREGROUND:
7265             ProcessFocusWhenForeground(sceneSession);
7266             if (!IsSessionVisibleForeground(sceneSession)) {
7267                 sceneSession->SetPostProcessProperty(true);
7268                 break;
7269             }
7270             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
7271             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
7272             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7273                                sceneSession->keepScreenLock_);
7274             HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7275                                sceneSession->viewKeepScreenLock_);
7276             UpdatePrivateStateAndNotify(persistentId);
7277             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7278                 ProcessSubSessionForeground(sceneSession);
7279             }
7280             break;
7281         case SessionState::STATE_BACKGROUND:
7282             NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
7283             RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
7284             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
7285             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
7286             HandleKeepScreenOn(sceneSession, false, WINDOW_SCREEN_LOCK_PREFIX, sceneSession->keepScreenLock_);
7287             HandleKeepScreenOn(sceneSession, false, VIEW_SCREEN_LOCK_PREFIX, sceneSession->viewKeepScreenLock_);
7288             UpdatePrivateStateAndNotify(persistentId);
7289             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7290                 ProcessSubSessionBackground(sceneSession);
7291             }
7292             break;
7293         case SessionState::STATE_CONNECT:
7294             SetSessionSnapshotSkipForAppProcess(sceneSession);
7295             SetSessionSnapshotSkipForAppBundleName(sceneSession);
7296             SetSessionWatermarkForAppProcess(sceneSession);
7297             break;
7298         case SessionState::STATE_DISCONNECT:
7299             if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
7300                 RemoveProcessSnapshotSkip(sceneSession->GetCallingPid());
7301                 RemoveProcessWatermarkPid(sceneSession->GetCallingPid());
7302             }
7303             break;
7304         default:
7305             break;
7306     }
7307 }
7308 
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)7309 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
7310 {
7311     auto persistentId = sceneSession->GetPersistentId();
7312     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7313     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7314     if (focusGroup == nullptr) {
7315         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7316         return;
7317     }
7318     bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7319     bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
7320     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
7321         persistentId == focusGroup->GetFocusedSessionId()) {
7322         if (focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground()) {
7323             focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7324             focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
7325             NotifyFocusStatus(sceneSession, true, focusGroup);
7326             sceneSession->NotifyHighlightChange(true);
7327         }
7328     } else if (!sceneSession->IsFocusedOnShow()) {
7329         if (IsSessionVisibleForeground(sceneSession)) {
7330             sceneSession->SetFocusedOnShow(true);
7331         }
7332     } else {
7333         if (Session::IsScbCoreEnabled()) {
7334             ProcessFocusWhenForegroundScbCore(sceneSession);
7335         } else {
7336             RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
7337         }
7338     }
7339 }
7340 
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)7341 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
7342 {
7343     if (sceneSession == nullptr) {
7344         TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
7345         return;
7346     }
7347     if (sceneSession->IsFocusableOnShow()) {
7348         if (IsSessionVisibleForeground(sceneSession)) {
7349             RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
7350         } else {
7351             PostProcessFocusState state = {true, true, true, FocusChangeReason::APP_FOREGROUND};
7352             sceneSession->SetPostProcessFocusState(state);
7353         }
7354     } else {
7355         TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
7356             sceneSession->GetPersistentId());
7357     }
7358 }
7359 
ProcessWindowModeType()7360 void SceneSessionManager::ProcessWindowModeType()
7361 {
7362     if (isScreenLocked_) {
7363         return;
7364     }
7365     NotifyRSSWindowModeTypeUpdate();
7366 }
7367 
IsSmallFoldProduct()7368 static bool IsSmallFoldProduct()
7369 {
7370     static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
7371     if (foldScreenType.empty()) {
7372         return false;
7373     }
7374     return foldScreenType[0] == SMALL_FOLD_PRODUCT_TYPE;
7375 }
7376 
IsInDefaultScreen(const sptr<SceneSession> & sceneSession)7377 bool SceneSessionManager::IsInDefaultScreen(const sptr<SceneSession>& sceneSession)
7378 {
7379     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
7380     return sceneSession->GetSessionProperty()->GetDisplayId() == defaultScreenId;
7381 }
7382 
IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession> & sceneSession,bool isSmallFold)7383 bool SceneSessionManager::IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession>& sceneSession, bool isSmallFold)
7384 {
7385     if (sceneSession == nullptr ||
7386         !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
7387         !sceneSession->GetRSVisible() ||
7388         !sceneSession->IsSessionForeground()) {
7389         return true;
7390     }
7391     if (isSmallFold && !IsInDefaultScreen(sceneSession)) {
7392         return true;
7393     }
7394     return false;
7395 }
7396 
CheckWindowModeType()7397 WindowModeType SceneSessionManager::CheckWindowModeType()
7398 {
7399     bool inSplit = false;
7400     bool inFloating = false;
7401     bool fullScreen = false;
7402     bool isSmallFold = IsSmallFoldProduct();
7403     {
7404         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7405         for (const auto& session : sceneSessionMap_) {
7406             if (IsNeedSkipWindowModeTypeCheck(session.second, isSmallFold)) {
7407                 continue;
7408             }
7409             auto mode = session.second->GetWindowMode();
7410             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
7411                 inSplit = true;
7412             }
7413             if (mode == WindowMode::WINDOW_MODE_FLOATING) {
7414                 inFloating = true;
7415             }
7416             if (WindowHelper::IsFullScreenWindow(mode)) {
7417                 fullScreen = true;
7418             }
7419         }
7420     }
7421 
7422     WindowModeType type;
7423     if (inSplit) {
7424         if (inFloating) {
7425             type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
7426         } else {
7427             type = WindowModeType::WINDOW_MODE_SPLIT;
7428         }
7429     } else {
7430         if (inFloating) {
7431             if (fullScreen) {
7432                 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
7433             } else {
7434                 type = WindowModeType::WINDOW_MODE_FLOATING;
7435             }
7436         } else if (fullScreen) {
7437             type = WindowModeType::WINDOW_MODE_FULLSCREEN;
7438         } else {
7439             type = WindowModeType::WINDOW_MODE_OTHER;
7440         }
7441     }
7442     return type;
7443 }
7444 
NotifyRSSWindowModeTypeUpdate()7445 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
7446 {
7447     WindowModeType type = CheckWindowModeType();
7448     if (lastWindowModeType_ == type) {
7449         return;
7450     }
7451     lastWindowModeType_ = type;
7452     TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
7453         static_cast<uint8_t>(type));
7454     SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
7455 }
7456 
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)7457 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
7458 {
7459     if (sceneSession == nullptr) {
7460         TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
7461         return;
7462     }
7463     std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
7464     for (auto& subSession : sceneSession->GetSubSession()) {
7465         if (subSession == nullptr) {
7466             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
7467             continue;
7468         }
7469         if (!subSession->GetSubSession().empty()) {
7470             ProcessSubSessionForeground(subSession);
7471         }
7472         if (subSession->IsTopmost()) {
7473             modalVec.push_back(subSession);
7474             TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
7475             continue;
7476         }
7477         const auto& state = subSession->GetSessionState();
7478         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7479             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
7480             continue;
7481         }
7482         RequestSessionFocus(subSession->GetPersistentId(), true);
7483         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
7484         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7485                            subSession->keepScreenLock_);
7486         HandleKeepScreenOn(subSession, subSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7487                            subSession->viewKeepScreenLock_);
7488     }
7489 
7490     for (const auto& modal : modalVec) {
7491         if (modal == nullptr) {
7492             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
7493             continue;
7494         }
7495         const auto& state = modal->GetSessionState();
7496         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7497             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
7498             continue;
7499         }
7500         auto modalSession = GetSceneSession(modal->GetPersistentId());
7501         if (modalSession == nullptr) {
7502             TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
7503             continue;
7504         }
7505         NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
7506         auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7507         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7508         if (focusGroup == nullptr) {
7509             TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7510             return;
7511         }
7512         auto focusedSessionId = focusGroup->GetFocusedSessionId();
7513         bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7514         if (modal->GetPersistentId() == focusedSessionId && needBlockNotifyFocusStatusUntilForeground) {
7515             focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7516             focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
7517             NotifyFocusStatus(modalSession, true, focusGroup);
7518         }
7519         HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7520                            modalSession->keepScreenLock_);
7521         HandleKeepScreenOn(modalSession, modalSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7522                            modalSession->viewKeepScreenLock_);
7523     }
7524 }
7525 
ProcessModalTopmostRequestFocusImmdediately(const sptr<SceneSession> & sceneSession)7526 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(const sptr<SceneSession>& sceneSession)
7527 {
7528     // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
7529     sptr<SceneSession> mainSession = nullptr;
7530     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7531         mainSession = sceneSession;
7532     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
7533         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
7534     }
7535     if (mainSession == nullptr) {
7536         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
7537         return WSError::WS_DO_NOTHING;
7538     }
7539 
7540     std::vector<sptr<SceneSession>> topmostVec;
7541     for (auto subSession : mainSession->GetSubSession()) {
7542         if (subSession && subSession->IsTopmost()) {
7543             topmostVec.push_back(subSession);
7544         }
7545     }
7546     auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
7547     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7548     auto conditionFunc =  [this, focusedSessionId](const sptr<SceneSession>& iter) {
7549         return iter && iter->GetPersistentId() == focusedSessionId;
7550     };
7551     if (std::find_if(topmostVec.begin(), topmostVec.end(), std::move(conditionFunc)) != topmostVec.end()) {
7552         TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId);
7553         return WSError::WS_OK;
7554     }
7555     WSError ret = WSError::WS_DO_NOTHING;
7556     for (auto topmostSession : topmostVec) {
7557         if (topmostSession == nullptr) {
7558             continue;
7559         }
7560         // no need to consider order, since rule of zOrder
7561         if (RequestSessionFocusImmediately(topmostSession->GetPersistentId(), false) == WSError::WS_OK) {
7562             ret = WSError::WS_OK;
7563         }
7564     }
7565     return ret;
7566 }
7567 
ProcessDialogRequestFocusImmdediately(const sptr<SceneSession> & sceneSession)7568 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(const sptr<SceneSession>& sceneSession)
7569 {
7570     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
7571     sptr<SceneSession> mainSession = nullptr;
7572     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7573         mainSession = sceneSession;
7574     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
7575         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
7576     }
7577     if (mainSession == nullptr) {
7578         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
7579         return WSError::WS_DO_NOTHING;
7580     }
7581     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
7582     auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
7583     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7584     auto conditionFunc =  [this, focusedSessionId](const sptr<Session>& iter) {
7585         return iter && iter->GetPersistentId() == focusedSessionId;
7586     };
7587     if (std::find_if(dialogVec.begin(), dialogVec.end(), std::move(conditionFunc)) != dialogVec.end()) {
7588         TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId);
7589         return WSError::WS_OK;
7590     }
7591     WSError ret = WSError::WS_DO_NOTHING;
7592     for (auto dialog : dialogVec) {
7593         if (dialog == nullptr) {
7594             continue;
7595         }
7596         // no need to consider order, since rule of zOrder
7597         if (RequestSessionFocusImmediately(dialog->GetPersistentId(), false) == WSError::WS_OK) {
7598             ret = WSError::WS_OK;
7599         }
7600     }
7601     return ret;
7602 }
7603 
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)7604 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
7605 {
7606     if (sceneSession == nullptr) {
7607         TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
7608         return;
7609     }
7610     for (auto& subSession : sceneSession->GetSubSession()) {
7611         if (subSession == nullptr) {
7612             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
7613             continue;
7614         }
7615         if (!subSession->GetSubSession().empty()) {
7616             ProcessSubSessionBackground(subSession);
7617         }
7618         const auto& state = subSession->GetSessionState();
7619         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7620             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
7621             continue;
7622         }
7623         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
7624         HandleKeepScreenOn(subSession, false, WINDOW_SCREEN_LOCK_PREFIX, subSession->keepScreenLock_);
7625         HandleKeepScreenOn(subSession, false, VIEW_SCREEN_LOCK_PREFIX, subSession->viewKeepScreenLock_);
7626         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
7627     }
7628     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
7629     for (const auto& dialog : dialogVec) {
7630         if (dialog == nullptr) {
7631             TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
7632             continue;
7633         }
7634         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
7635         if (dialogSession == nullptr) {
7636             TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
7637             continue;
7638         }
7639         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
7640         HandleKeepScreenOn(dialogSession, false, WINDOW_SCREEN_LOCK_PREFIX, dialogSession->keepScreenLock_);
7641         HandleKeepScreenOn(dialogSession, false, VIEW_SCREEN_LOCK_PREFIX, dialogSession->viewKeepScreenLock_);
7642         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
7643     }
7644     for (const auto& toastSession : sceneSession->GetToastSession()) {
7645         if (toastSession == nullptr) {
7646             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
7647             continue;
7648         }
7649         const auto& state = toastSession->GetSessionState();
7650         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7651             TLOGD(WmsLogTag::WMS_TOAST, "toast session is not active");
7652             continue;
7653         }
7654         NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
7655         HandleKeepScreenOn(toastSession, false, WINDOW_SCREEN_LOCK_PREFIX, toastSession->keepScreenLock_);
7656         HandleKeepScreenOn(toastSession, false, VIEW_SCREEN_LOCK_PREFIX, toastSession->viewKeepScreenLock_);
7657         UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
7658         toastSession->SetActive(false);
7659         toastSession->BackgroundTask();
7660     }
7661 }
7662 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)7663 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
7664     const sptr<WindowSessionProperty>& property)
7665 {
7666     if (sceneSession == nullptr) {
7667         TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
7668         return WSError::WS_ERROR_NULLPTR;
7669     }
7670     auto sessionProperty = sceneSession->GetSessionProperty();
7671     uint32_t flags = property->GetWindowFlags();
7672     uint32_t oldFlags = sessionProperty->GetWindowFlags();
7673     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
7674          (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
7675         !property->GetSystemCalling()) {
7676         TLOGE(WmsLogTag::DEFAULT, "permission denied");
7677         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7678     }
7679     sessionProperty->SetWindowFlags(flags);
7680     CheckAndNotifyWaterMarkChangedResult();
7681     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
7682         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
7683     }
7684     TLOGI(WmsLogTag::DEFAULT, "set flags: %{public}u", flags);
7685     return WSError::WS_OK;
7686 }
7687 
CheckAndNotifyWaterMarkChangedResult()7688 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
7689 {
7690     bool currentWaterMarkShowState = false;
7691     {
7692         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7693         for (const auto& [_, session] : sceneSessionMap_) {
7694             if (!session) {
7695                 continue;
7696             }
7697             bool hasWaterMark = session->GetSessionProperty()->GetWindowFlags() &
7698                 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
7699             bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
7700             if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
7701                 currentWaterMarkShowState = true;
7702                 break;
7703             }
7704         }
7705         if (combinedExtWindowFlags_.waterMarkFlag) {
7706             TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
7707             currentWaterMarkShowState = true;
7708         }
7709     }
7710     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
7711         lastWaterMarkShowState_ = currentWaterMarkShowState;
7712         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
7713     }
7714 }
7715 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)7716 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
7717 {
7718     TLOGI(WmsLogTag::DEFAULT, "hasWaterMark: %{public}u", static_cast<uint32_t>(hasWaterMark));
7719     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
7720     return WSError::WS_OK;
7721 }
7722 
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const7723 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
7724 {
7725     if (!bundleMgr_) {
7726         TLOGE(WmsLogTag::DEFAULT, "bundle manager is nullptr.");
7727         return;
7728     }
7729 
7730     AAFwk::Want want;
7731     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
7732     auto uid = abilityInfo.uid;
7733     want.SetParam("uid", uid);
7734     bundleMgr_->ProcessPreload(want);
7735 }
7736 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)7737 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
7738 {
7739     auto sceneSession = GetSceneSession(persistentId);
7740     if (sceneSession == nullptr) {
7741         TLOGE(WmsLogTag::WMS_MAIN, " sceneSession is nullptr.");
7742         return;
7743     }
7744 
7745     const auto& sessionInfo = sceneSession->GetSessionInfo();
7746     if (IsAtomicServiceFreeInstall(sessionInfo)) {
7747         TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
7748             sceneSession->GetPersistentId(), sceneSession->GetWindowType());
7749         FillSessionInfo(sceneSession);
7750     }
7751     TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
7752         sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
7753         sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
7754     auto abilityInfo = sessionInfo.abilityInfo;
7755     if (abilityInfo == nullptr) {
7756         TLOGE(WmsLogTag::WMS_MAIN, " abilityInfo is null, Id: %{public}d", persistentId);
7757         return;
7758     }
7759 
7760     [this, persistentId] {
7761         auto task = [persistentId] {
7762             AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
7763         };
7764         TLOGNI(WmsLogTag::DEFAULT, "Post CompleteFirstFrameDrawing task. Id: %{public}d", persistentId);
7765         eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
7766     }();
7767 
7768     auto task = [this, abilityInfo, sceneSession, persistentId] {
7769         if (!sceneSession->GetSessionInfo().isSystem_ && !(abilityInfo->excludeFromMissions)) {
7770             TLOGND(WmsLogTag::WMS_PATTERN, "NotifyCreated, id: %{public}d", persistentId);
7771             listenerController_->NotifySessionLifecycleEvent(
7772                 ISessionLifecycleListener::SessionLifecycleEvent::CREATED, sceneSession->GetSessionInfo());
7773         }
7774         ProcessPreload(*abilityInfo);
7775     };
7776     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
7777 }
7778 
NotifySessionMovedToFront(int32_t persistentId)7779 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
7780 {
7781     auto sceneSession = GetSceneSession(persistentId);
7782     if (sceneSession == nullptr) {
7783         TLOGE(WmsLogTag::DEFAULT, "session is invalid with %{public}d", persistentId);
7784         return;
7785     }
7786     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
7787            sceneSession->GetSessionInfo().isSystem_);
7788     if (!sceneSession->GetSessionInfo().isSystem_ &&
7789         sceneSession->GetSessionInfo().abilityInfo &&
7790         !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
7791         listenerController_->NotifySessionMovedToFront(persistentId);
7792         listenerController_->NotifySessionLifecycleEvent(
7793             ISessionLifecycleListener::SessionLifecycleEvent::FOREGROUND, sceneSession->GetSessionInfo());
7794     }
7795 }
7796 
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)7797 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
7798 {
7799     TLOGI(WmsLogTag::WMS_MAIN, "in");
7800     const char* const where = __func__;
7801     auto task = [this, &token, &label, where]() {
7802         auto sceneSession = FindSessionByToken(token);
7803         if (sceneSession == nullptr) {
7804             TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
7805             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
7806         }
7807         sceneSession->SetSessionLabel(label);
7808         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
7809             where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
7810         if (!sceneSession->GetSessionInfo().isSystem_) {
7811             TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
7812             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
7813         }
7814         return WSError::WS_OK;
7815     };
7816     return taskScheduler_->PostSyncTask(task, where);
7817 }
7818 
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)7819 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
7820     const std::shared_ptr<Media::PixelMap>& icon)
7821 {
7822     TLOGI(WmsLogTag::WMS_MAIN, "in");
7823     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7824         TLOGE(WmsLogTag::WMS_MAIN, "The caller is not system-app, can not use system-api");
7825         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7826     }
7827     const char* const where = __func__;
7828     auto task = [this, &token, &icon, where]() {
7829         auto sceneSession = FindSessionByToken(token);
7830         if (sceneSession == nullptr) {
7831             TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
7832             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
7833         }
7834         sceneSession->SetSessionIcon(icon);
7835         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
7836             where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
7837         if (!sceneSession->GetSessionInfo().isSystem_ &&
7838             sceneSession->GetSessionInfo().abilityInfo &&
7839             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
7840             TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
7841             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
7842         }
7843         return WSError::WS_OK;
7844     };
7845     return taskScheduler_->PostSyncTask(task, where);
7846 }
7847 
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)7848 WSError SceneSessionManager::IsValidSessionIds(
7849     const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
7850 {
7851     TLOGI(WmsLogTag::DEFAULT, "in");
7852     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7853     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
7854         auto search = sceneSessionMap_.find(sessionIds.at(i));
7855         if (search == sceneSessionMap_.end() || search->second == nullptr) {
7856             results.push_back(false);
7857             continue;
7858         }
7859         results.push_back(true);
7860     }
7861     return WSError::WS_OK;
7862 }
7863 
RegisterSessionListener(const sptr<ISessionListener> & listener)7864 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
7865 {
7866     TLOGI(WmsLogTag::DEFAULT, "in");
7867     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7868         TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
7869         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7870     }
7871     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7872         TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
7873         return WSError::WS_ERROR_INVALID_PERMISSION;
7874     }
7875     auto task = [this, &listener] {
7876         WSError ret = listenerController_->AddSessionListener(listener);
7877         // app continue report for distributed scheduled service
7878         SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
7879             static_cast<int32_t>(ret));
7880         return ret;
7881     };
7882     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
7883 }
7884 
UnRegisterSessionListener(const sptr<ISessionListener> & listener)7885 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
7886 {
7887     TLOGI(WmsLogTag::DEFAULT, "in");
7888     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7889         TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
7890         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7891     }
7892     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7893         TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
7894         return WSError::WS_ERROR_INVALID_PERMISSION;
7895     }
7896     auto task = [this, &listener] {
7897         listenerController_->DelSessionListener(listener);
7898         return WSError::WS_OK;
7899     };
7900     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
7901 }
7902 
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)7903 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
7904                                              std::vector<SessionInfoBean>& sessionInfos)
7905 {
7906     TLOGI(WmsLogTag::DEFAULT, "num max %{public}d", numMax);
7907     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7908         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
7909         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7910     }
7911     if (!SessionPermission::VerifySessionPermission()) {
7912         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
7913         return WSError::WS_ERROR_INVALID_PERMISSION;
7914     }
7915     auto task = [this, &deviceId, numMax, &sessionInfos]() {
7916         if (CheckIsRemote(deviceId)) {
7917             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
7918             if (ret != ERR_OK) {
7919                 return WSError::WS_ERROR_INVALID_PARAM;
7920             } else {
7921                 return WSError::WS_OK;
7922             }
7923         }
7924         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7925         std::vector<sptr<SceneSession>> sceneSessionInfos;
7926         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7927         for (const auto& [_, sceneSession] : sceneSessionMap_) {
7928             if (sceneSession == nullptr) {
7929                 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
7930                 continue;
7931             }
7932             const auto& sessionInfo = sceneSession->GetSessionInfo();
7933             if (sessionInfo.isSystem_) {
7934                 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
7935                 continue;
7936             }
7937             auto want = sessionInfo.want;
7938             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
7939                 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
7940                     "or want bundleName is empty", sceneSession->GetPersistentId());
7941                 continue;
7942             }
7943             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
7944                 break;
7945             }
7946             TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfos session: %{public}d, bundleName:%{public}s",
7947                 sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str());
7948             sceneSessionInfos.emplace_back(sceneSession);
7949         }
7950         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
7951     };
7952     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
7953 }
7954 
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)7955 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
7956 {
7957     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
7958     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
7959         TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
7960         return WSError::WS_ERROR_INVALID_PERMISSION;
7961     }
7962     if (pid < 0) {
7963         return WSError::WS_ERROR_INVALID_PARAM;
7964     }
7965     auto task = [this, pid, &windowStates] {
7966         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7967         for (const auto& [_, sceneSession] : sceneSessionMap_) {
7968             if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
7969                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7970                 MainWindowState windowState;
7971                 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
7972                 windowState.isVisible_ = sceneSession->GetRSVisible();
7973                 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
7974                 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
7975                 windowStates.emplace_back(windowState);
7976             }
7977         }
7978         return WSError::WS_OK;
7979     };
7980     return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
7981 }
7982 
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)7983 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
7984                                                std::vector<SessionInfoBean>& sessionInfos)
7985 {
7986     TLOGI(WmsLogTag::DEFAULT, "begin");
7987     int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
7988     if (result != ERR_OK) {
7989         TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
7990         return result;
7991     }
7992     return ERR_OK;
7993 }
7994 
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)7995 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
7996                                             int32_t persistentId, SessionInfoBean& sessionInfo)
7997 {
7998     TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
7999     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8000         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
8001         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8002     }
8003     if (!SessionPermission::VerifySessionPermission()) {
8004         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
8005         return WSError::WS_ERROR_INVALID_PERMISSION;
8006     }
8007     return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &sessionInfo]() {
8008         if (CheckIsRemote(deviceId)) {
8009             if (GetRemoteSessionInfo(deviceId, persistentId, sessionInfo) != ERR_OK) {
8010                 return WSError::WS_ERROR_INVALID_PARAM;
8011             } else {
8012                 return WSError::WS_OK;
8013             }
8014         }
8015 
8016         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8017         if (auto iter = sceneSessionMap_.find(persistentId); iter != sceneSessionMap_.end()) {
8018             auto sceneSession = iter->second;
8019             if (sceneSession == nullptr) {
8020                 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d is nullptr", persistentId);
8021                 return WSError::WS_ERROR_INVALID_PARAM;
8022             }
8023             const auto& sceneSessionInfo = sceneSession->GetSessionInfo();
8024             if (sceneSessionInfo.isSystem_) {
8025                 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d  isSystemScene", persistentId);
8026                 return WSError::WS_ERROR_INVALID_PARAM;
8027             }
8028             auto want = sceneSessionInfo.want;
8029             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
8030                 want->GetElement().GetBundleName().empty()) {
8031                 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
8032                     "or want bundleName is empty", persistentId);
8033                 return WSError::WS_ERROR_INTERNAL_ERROR;
8034             }
8035             TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
8036                 sceneSessionInfo.bundleName_.c_str());
8037             return SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
8038         } else {
8039             TLOGNW(WmsLogTag::WMS_LIFE, "sessionId: %{public}d not found", persistentId);
8040             return WSError::WS_ERROR_INVALID_PARAM;
8041         }
8042     }, __func__);
8043 }
8044 
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)8045 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
8046     SessionInfoBean& sessionInfo)
8047 {
8048     TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
8049         continueSessionId.c_str());
8050     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8051         TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
8052         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8053     }
8054     if (!SessionPermission::VerifySessionPermission()) {
8055         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
8056         return WSError::WS_ERROR_INVALID_PERMISSION;
8057     }
8058     return taskScheduler_->PostSyncTask([this, continueSessionId, &sessionInfo]() {
8059         WSError ret = WSError::WS_ERROR_INVALID_SESSION;
8060         {
8061             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8062             for (const auto& [_, sceneSession] : sceneSessionMap_) {
8063                 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
8064                     ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
8065                     break;
8066                 }
8067             }
8068         }
8069 
8070         TLOGNI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
8071         // app continue report for distributed scheduled service
8072         SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
8073             static_cast<int32_t>(ret));
8074         return ret;
8075     }, __func__);
8076 }
8077 
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)8078 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
8079                                               int32_t persistentId, SessionInfoBean& sessionInfo)
8080 {
8081     TLOGI(WmsLogTag::DEFAULT, "in");
8082     std::vector<SessionInfoBean> sessionVector;
8083     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
8084     if (result != ERR_OK) {
8085         return result;
8086     }
8087     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
8088         if (iter->id == persistentId) {
8089             sessionInfo = *iter;
8090             return ERR_OK;
8091         }
8092     }
8093     TLOGW(WmsLogTag::DEFAULT, "missionId not found");
8094     return ERR_INVALID_VALUE;
8095 }
8096 
CheckIsRemote(const std::string & deviceId)8097 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
8098 {
8099     if (deviceId.empty()) {
8100         TLOGI(WmsLogTag::DEFAULT, "empty");
8101         return false;
8102     }
8103     std::string localDeviceId;
8104     if (!GetLocalDeviceId(localDeviceId)) {
8105         TLOGE(WmsLogTag::DEFAULT, "GetLocalDeviceId failed");
8106         return false;
8107     }
8108     if (localDeviceId == deviceId) {
8109         TLOGI(WmsLogTag::DEFAULT, "deviceId is local.");
8110         return false;
8111     }
8112     TLOGD(WmsLogTag::DEFAULT, "Checked deviceId=%{public}s", AnonymizeDeviceId(deviceId).c_str());
8113     return true;
8114 }
8115 
GetLocalDeviceId(std::string & localDeviceId)8116 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
8117 {
8118     auto localNode = std::make_unique<NodeBasicInfo>();
8119     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
8120     if (errCode != ERR_OK) {
8121         TLOGE(WmsLogTag::DEFAULT, "GetLocalNodeDeviceInfo errCode=%{public}d", errCode);
8122         return false;
8123     }
8124     if (localNode != nullptr) {
8125         localDeviceId = localNode->networkId;
8126         TLOGD(WmsLogTag::DEFAULT, "get local deviceId, deviceId=%{public}s", AnonymizeDeviceId(localDeviceId).c_str());
8127         return true;
8128     }
8129     TLOGE(WmsLogTag::DEFAULT, "localDeviceId null");
8130     return false;
8131 }
8132 
AnonymizeDeviceId(const std::string & deviceId)8133 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
8134 {
8135     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
8136         return EMPTY_DEVICE_ID;
8137     }
8138     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
8139     anonDeviceId.append("******");
8140     return anonDeviceId;
8141 }
8142 
DumpSessionAll(std::vector<std::string> & infos)8143 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
8144 {
8145     TLOGI(WmsLogTag::DEFAULT, "in.");
8146     if (!SessionPermission::IsSystemCalling()) {
8147         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
8148         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8149     }
8150 
8151     return taskScheduler_->PostSyncTask([this, &infos]() {
8152         infos.push_back("User ID #" + std::to_string(currentUserId_));
8153         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8154         for (const auto& [_, session] : sceneSessionMap_) {
8155             if (session) {
8156                 session->DumpSessionInfo(infos);
8157             }
8158         }
8159         return WSError::WS_OK;
8160     }, __func__);
8161 }
8162 
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)8163 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
8164 {
8165     TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
8166     if (!SessionPermission::IsSystemCalling()) {
8167         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
8168         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8169     }
8170 
8171     return taskScheduler_->PostSyncTask([this, persistentId, &infos]() {
8172         infos.push_back("User ID #" + std::to_string(currentUserId_));
8173         auto session = GetSceneSession(persistentId);
8174         if (session) {
8175             session->DumpSessionInfo(infos);
8176         } else {
8177             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
8178         }
8179         return WSError::WS_OK;
8180     }, __func__);
8181 }
8182 
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)8183 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
8184     const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
8185 {
8186     if (bundleMgr_ == nullptr) {
8187         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
8188         return WSError::WS_ERROR_NULLPTR;
8189     }
8190     const auto& elementName = want.GetElement();
8191     int32_t ret{0};
8192     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
8193         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
8194         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
8195         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
8196         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
8197         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
8198     std::vector<AppExecFwk::BundleInfo> bundleInfos;
8199     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
8200         TLOGD(WmsLogTag::DEFAULT, "want is empty queryAllAbilityInfos");
8201         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
8202         if (ret) {
8203             TLOGE(WmsLogTag::DEFAULT, "Query all ability infos from BMS failed!");
8204             return WSError::WS_ERROR_INVALID_PARAM;
8205         }
8206     } else if (!elementName.GetBundleName().empty()) {
8207         AppExecFwk::BundleInfo bundleInfo;
8208         TLOGD(WmsLogTag::DEFAULT, "bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
8209         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
8210         if (ret) {
8211             TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed!");
8212             return WSError::WS_ERROR_INVALID_PARAM;
8213         }
8214         bundleInfos.push_back(bundleInfo);
8215     } else {
8216         TLOGE(WmsLogTag::DEFAULT, "invalid want:%{public}s", want.ToString().c_str());
8217         return WSError::WS_ERROR_INVALID_PARAM;
8218     }
8219     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
8220 }
8221 
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)8222 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
8223     const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
8224 {
8225     if (bundleMgr_ == nullptr) {
8226         TLOGE(WmsLogTag::WMS_RECOVER, "bundleMgr is nullptr");
8227         return WSError::WS_ERROR_NULLPTR;
8228     }
8229     if (bundleNames.empty()) {
8230         TLOGE(WmsLogTag::WMS_RECOVER, "bundleNames is empty");
8231         return WSError::WS_ERROR_INVALID_PARAM;
8232     }
8233     auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
8234                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
8235                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
8236                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
8237                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
8238                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
8239     std::vector<AppExecFwk::BundleInfo> bundleInfos;
8240     auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
8241     if (ret) {
8242         TLOGE(WmsLogTag::WMS_RECOVER, "Query batch ability infos from BMS failed!");
8243         return WSError::WS_ERROR_INVALID_PARAM;
8244     }
8245     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
8246 }
8247 
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)8248 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
8249     const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
8250 {
8251     if (bundleMgr_ == nullptr) {
8252         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
8253         return WSError::WS_ERROR_NULLPTR;
8254     }
8255     auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
8256         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
8257         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
8258         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
8259         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
8260         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
8261     AppExecFwk::BundleInfo bundleInfo;
8262     if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
8263         TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
8264         return WSError::WS_ERROR_INVALID_PARAM;
8265     }
8266     auto& hapModulesList = bundleInfo.hapModuleInfos;
8267     if (hapModulesList.empty()) {
8268         TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
8269         return WSError::WS_ERROR_INVALID_PARAM;
8270     }
8271     auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
8272     for (auto& hapModule : hapModulesList) {
8273         auto& abilityInfoList = hapModule.abilityInfos;
8274         for (auto& abilityInfo : abilityInfoList) {
8275             if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
8276                 scbAbilityInfo.abilityInfo_ = abilityInfo;
8277                 scbAbilityInfo.sdkVersion_ = sdkVersion;
8278                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
8279                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
8280                 return WSError::WS_OK;
8281             }
8282         }
8283     }
8284     TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
8285     return WSError::WS_ERROR_INVALID_PARAM;
8286 }
8287 
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)8288 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
8289     std::vector<SCBAbilityInfo>& scbAbilityInfos)
8290 {
8291     if (bundleInfos.empty()) {
8292         TLOGE(WmsLogTag::DEFAULT, "bundleInfos is empty");
8293         return WSError::WS_ERROR_INVALID_PARAM;
8294     }
8295     for (auto& bundleInfo : bundleInfos) {
8296         auto& hapModulesList = bundleInfo.hapModuleInfos;
8297         auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
8298         if (hapModulesList.empty()) {
8299             TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty");
8300             continue;
8301         }
8302         if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
8303             bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
8304             auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
8305                 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
8306             if (iter != hapModulesList.end()) {
8307                 SCBAbilityInfo scbAbilityInfo;
8308                 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
8309                 scbAbilityInfo.sdkVersion_ = sdkVersion;
8310                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
8311                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
8312                 scbAbilityInfos.push_back(scbAbilityInfo);
8313                 continue;
8314             }
8315         }
8316         for (auto& hapModule : hapModulesList) {
8317             auto& abilityInfoList = hapModule.abilityInfos;
8318             for (auto& abilityInfo : abilityInfoList) {
8319                 SCBAbilityInfo scbAbilityInfo;
8320                 scbAbilityInfo.abilityInfo_ = abilityInfo;
8321                 scbAbilityInfo.sdkVersion_ = sdkVersion;
8322                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
8323                 scbAbilityInfos.push_back(scbAbilityInfo);
8324             }
8325         }
8326     }
8327     return WSError::WS_OK;
8328 }
8329 
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)8330 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
8331 {
8332     if (abilityInfo.orientationId == 0) {
8333         return;
8334     }
8335     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
8336     if (resConfig == nullptr) {
8337         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
8338         return;
8339     }
8340     std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
8341         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
8342     if (resourceMgr == nullptr) {
8343         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
8344         return;
8345     }
8346     std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
8347     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
8348         TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
8349     }
8350     std::string orientation;
8351     auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
8352     if (ret != Global::Resource::RState::SUCCESS) {
8353         TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
8354             static_cast<int32_t>(ret), abilityInfo.orientationId);
8355         return;
8356     }
8357     if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
8358         TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
8359         return;
8360     }
8361     abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
8362 }
8363 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)8364 WSError SceneSessionManager::TerminateSessionNew(
8365     const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
8366 {
8367     if (info == nullptr) {
8368         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
8369         return WSError::WS_ERROR_INVALID_PARAM;
8370     }
8371     TLOGI(WmsLogTag::WMS_LIFE,
8372         "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
8373         info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
8374     int32_t callingPid = IPCSkeleton::GetCallingPid();
8375     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
8376     auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
8377         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
8378         if (sceneSession == nullptr) {
8379             TLOGNE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
8380             return WSError::WS_ERROR_INVALID_PARAM;
8381         }
8382         const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
8383         if (!pidCheck &&
8384             !SessionPermission::VerifyPermissionByCallerToken(callerToken,
8385                 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8386             TLOGNE(WmsLogTag::WMS_LIFE,
8387                 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
8388                 sceneSession->GetCallingPid(), callingPid);
8389             return WSError::WS_ERROR_INVALID_PERMISSION;
8390         }
8391         WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
8392         return errCode;
8393     };
8394     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
8395 }
8396 
SetVmaCacheStatus(bool flag)8397 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
8398 {
8399     TLOGI(WmsLogTag::DEFAULT, "flag: %{public}d", flag);
8400     RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
8401     return WSError::WS_OK;
8402 }
8403 
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)8404 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
8405                                                 SessionSnapshot& snapshot, bool isLowResolution)
8406 {
8407     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
8408     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8409         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
8410         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8411     }
8412     if (!SessionPermission::VerifySessionPermission()) {
8413         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
8414         return WSError::WS_ERROR_INVALID_PERMISSION;
8415     }
8416     return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &snapshot, isLowResolution]() {
8417         if (CheckIsRemote(deviceId)) {
8418             if (GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot) != ERR_OK) {
8419                 return WSError::WS_ERROR_INVALID_PARAM;
8420             } else {
8421                 return WSError::WS_OK;
8422             }
8423         }
8424         auto sceneSession = GetSceneSession(persistentId);
8425         if (!sceneSession) {
8426             TLOGNE(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
8427             return WSError::WS_ERROR_INVALID_PARAM;
8428         }
8429         const auto& sessionInfo = sceneSession->GetSessionInfo();
8430         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
8431             TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
8432                    sceneSession->GetPersistentId());
8433         }
8434         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
8435         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
8436         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
8437         if (auto oriSnapshot = sceneSession->Snapshot()) {
8438             if (isLowResolution) {
8439                 OHOS::Media::InitializationOptions options;
8440                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
8441                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
8442                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
8443                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
8444             } else {
8445                 snapshot.snapshot = oriSnapshot;
8446             }
8447         }
8448         return WSError::WS_OK;
8449     }, __func__);
8450 }
8451 
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)8452 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
8453 {
8454     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
8455         TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
8456         return WMError::WM_ERROR_NOT_SYSTEM_APP;
8457     }
8458     return taskScheduler_->PostSyncTask([this, persistentId, &snapshot]() {
8459         auto sceneSession = GetSceneSession(persistentId);
8460         if (!sceneSession) {
8461             TLOGNW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
8462             return WMError::WM_ERROR_INVALID_PARAM;
8463         }
8464         const auto& sessionInfo = sceneSession->GetSessionInfo();
8465         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
8466             TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
8467                 sceneSession->GetPersistentId());
8468         }
8469         snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
8470         snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
8471         snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
8472         float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
8473         if (auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale, false)) {
8474             if (sceneSession->GetFloatingScale() > 1.0f) {
8475                 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
8476             }
8477             snapshot.snapshot = oriSnapshot;
8478             TLOGNI(WmsLogTag::WMS_SYSTEM, "snapshot WxH=%{public}dx%{public}d",
8479                 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
8480             return WMError::WM_OK;
8481         }
8482         return WMError::WM_ERROR_NULLPTR;
8483     }, __func__);
8484 }
8485 
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)8486 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
8487 {
8488     if (!SessionPermission::IsSACalling()) {
8489         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Permission denied!");
8490         return WSError::WS_ERROR_INVALID_PERMISSION;
8491     }
8492     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "PersistentId=%{public}d", persistentId);
8493     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8494     if (sceneSession == nullptr) {
8495         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sceneSession is nullptr");
8496         return WSError::WS_ERROR_NULLPTR;
8497     }
8498     return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
8499 }
8500 
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)8501 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
8502                                                       AAFwk::MissionSnapshot& sessionSnapshot)
8503 {
8504     TLOGI(WmsLogTag::DEFAULT, "begin");
8505     int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
8506         sessionId, sessionSnapshot);
8507     if (result != ERR_OK) {
8508         TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
8509         return result;
8510     }
8511     return ERR_OK;
8512 }
8513 
GetCollaboratorByType(int32_t collaboratorType)8514 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
8515 {
8516     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
8517     std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
8518     auto iter = collaboratorMap_.find(collaboratorType);
8519     if (iter == collaboratorMap_.end()) {
8520         TLOGE(WmsLogTag::WMS_MAIN, "Fail to found collaborator with type: %{public}d", collaboratorType);
8521         return collaborator;
8522     }
8523     collaborator = iter->second;
8524     if (collaborator == nullptr) {
8525         TLOGE(WmsLogTag::WMS_MAIN, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
8526     }
8527     return collaborator;
8528 }
8529 
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)8530 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
8531 {
8532     const char* const where = __func__;
8533     auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession), where]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
8534         auto sceneSession = weakSceneSession.promote();
8535         if (sceneSession == nullptr) {
8536             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is nullptr", where);
8537             return WSError::WS_ERROR_NULLPTR;
8538         }
8539         auto persistentId = sceneSession->GetPersistentId();
8540         if (!GetSceneSession(persistentId)) {
8541             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is invalid, id:%{public}d", where, persistentId);
8542             return WSError::WS_ERROR_INVALID_SESSION;
8543         }
8544         const auto& sessionInfo = sceneSession->GetSessionInfo();
8545         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: state:%{public}d, id:%{public}d",
8546             where, sessionInfo.callState_, persistentId);
8547         auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8548         bool isColdStart = false;
8549         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
8550         if (isColdStart) {
8551             TLOGNI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
8552                 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
8553             sceneSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
8554             sceneSession->ResetSessionConnectState();
8555         }
8556         return WSError::WS_OK;
8557     };
8558     std::string taskName = "RequestSceneSessionByCall:PID:" +
8559         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
8560     taskScheduler_->PostAsyncTask(task, taskName);
8561     return WSError::WS_OK;
8562 }
8563 
StartAbilityBySpecified(const SessionInfo & sessionInfo)8564 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
8565 {
8566     const char* const where = __func__;
8567     auto task = [this, sessionInfo, where]() {
8568         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: bundleName: %{public}s, "
8569             "moduleName: %{public}s, abilityName: %{public}s", where,
8570             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
8571         AAFwk::Want want;
8572         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
8573         if (sessionInfo.want != nullptr) {
8574             want.SetParams(sessionInfo.want->GetParams());
8575             want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int>(sessionInfo.screenId_));
8576         }
8577         AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
8578     };
8579 
8580     taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
8581 }
8582 
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)8583 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
8584 {
8585     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
8586     if (pid == -1) {
8587         TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
8588         return;
8589     }
8590     int32_t ret = HiSysEventWrite(
8591         HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
8592         "WINDOW_STATE_ERROR",
8593         HiviewDFX::HiSysEvent::EventType::FAULT,
8594         "PID", pid,
8595         "PERSISTENT_ID", persistentId);
8596     if (ret != 0) {
8597         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
8598     }
8599     auto task = [this, pid] {
8600         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8601         for (const auto& [_, sceneSession] : sceneSessionMap_) {
8602             if (!sceneSession || pid != sceneSession->GetCallingPid() ||
8603                 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
8604                 continue;
8605             }
8606             auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8607             TLOGNI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
8608                 abilitySessionInfo->persistentId);
8609             sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
8610         }
8611     };
8612     // delay 2000ms, wait for hidumper
8613     taskScheduler_->PostAsyncTask(task, __func__, 2000);
8614 }
8615 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)8616 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
8617 {
8618     if (!targetToken) {
8619         TLOGE(WmsLogTag::DEFAULT, "Token is null, cannot find main window");
8620         return nullptr;
8621     }
8622 
8623     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8624     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
8625         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8626             if (pair.second->IsTerminated()) {
8627                 return false;
8628             }
8629             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8630                 return pair.second->GetAbilityToken() == targetToken;
8631             }
8632             return false;
8633         });
8634     if (iter == sceneSessionMap_.end()) {
8635         TLOGE(WmsLogTag::DEFAULT, "Cannot find session");
8636         return nullptr;
8637     }
8638     return iter->second;
8639 }
8640 
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)8641 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
8642 {
8643     if (!SessionPermission::IsSystemCalling()) {
8644         TLOGE(WmsLogTag::WMS_DIALOG, "permission denied!");
8645         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8646     }
8647     if (targetToken == nullptr) {
8648         TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
8649         return WSError::WS_ERROR_NULLPTR;
8650     }
8651 
8652     auto task = [this, persistentId, targetToken]() {
8653         auto sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
8654         if (sceneSession == nullptr) {
8655             TLOGNE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
8656             return WSError::WS_ERROR_NULLPTR;
8657         }
8658         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
8659             TLOGNE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", sceneSession->GetWindowType());
8660             return WSError::WS_OK;
8661         }
8662         sceneSession->dialogTargetToken_ = targetToken;
8663         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
8664         if (parentSession == nullptr) {
8665             sceneSession->NotifyDestroy();
8666             return WSError::WS_ERROR_INVALID_PARAM;
8667         }
8668         sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
8669         sptr<WindowSessionProperty> property = sceneSession->GetSessionProperty();
8670         auto displayId = parentProperty->GetDisplayId();
8671         property->SetDisplayId(displayId);
8672         sceneSession->SetScreenId(displayId);
8673         sceneSession->SetParentSession(parentSession);
8674         sceneSession->SetParentPersistentId(parentSession->GetPersistentId());
8675         sceneSession->SetClientDisplayId(parentSession->GetClientDisplayId());
8676         UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
8677         TLOGNI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
8678             persistentId, parentSession->GetPersistentId());
8679         return WSError::WS_OK;
8680     };
8681     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
8682 }
8683 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)8684 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
8685     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
8686 {
8687     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
8688 }
8689 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)8690 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
8691     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
8692 {
8693     auto isSaCall = SessionPermission::IsSACalling();
8694     if (!isSaCall) {
8695         TLOGE(WmsLogTag::DEFAULT, "The interface only support for sa call");
8696         return WMError::WM_ERROR_INVALID_PERMISSION;
8697     }
8698     auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
8699         std::map<int32_t, sptr<SceneSession>>::iterator iter;
8700         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8701         for (auto missionId : missionIds) {
8702             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
8703             if (iter == sceneSessionMap_.end()) {
8704                 continue;
8705             }
8706             auto sceneSession = iter->second;
8707             if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
8708                 continue;
8709             }
8710             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
8711             if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
8712                 surfaceNodeIds.push_back(missionId);
8713                 continue;
8714             }
8715             if (sceneSession->GetLeashWinSurfaceNode()) {
8716                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
8717             }
8718         }
8719         return WMError::WM_OK;
8720     };
8721     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
8722 }
8723 
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)8724 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
8725     const sptr<IWindowManagerAgent>& windowManagerAgent)
8726 {
8727     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
8728         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
8729         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
8730         if (!SessionPermission::IsSystemCalling()) {
8731             TLOGE(WmsLogTag::DEFAULT, "permission denied!");
8732             return WMError::WM_ERROR_NOT_SYSTEM_APP;
8733         }
8734     } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
8735         if (!SessionPermission::IsSystemServiceCalling()) {
8736             return WMError::WM_ERROR_INVALID_PERMISSION;
8737         }
8738     }
8739     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
8740         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
8741         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
8742         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
8743         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
8744         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY) {
8745         if (!SessionPermission::IsSACalling()) {
8746             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
8747             return WMError::WM_ERROR_INVALID_PERMISSION;
8748         }
8749     }
8750     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
8751         TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
8752         return WMError::WM_ERROR_NULLPTR;
8753     }
8754     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8755     auto task = [this, windowManagerAgent, type, callingPid]() {
8756         return SessionManagerAgentController::GetInstance()
8757             .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
8758     };
8759     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
8760 }
8761 
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)8762 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
8763     const sptr<IWindowManagerAgent>& windowManagerAgent)
8764 {
8765     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
8766         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
8767         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
8768         if (!SessionPermission::IsSystemCalling()) {
8769             TLOGE(WmsLogTag::DEFAULT, "IsSystemCalling permission denied!");
8770             return WMError::WM_ERROR_NOT_SYSTEM_APP;
8771         }
8772     }
8773     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
8774         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
8775         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
8776         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
8777         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
8778         if (!SessionPermission::IsSACalling()) {
8779             TLOGE(WmsLogTag::WMS_LIFE, "IsSACalling permission denied!");
8780             return WMError::WM_ERROR_INVALID_PERMISSION;
8781         }
8782     }
8783     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
8784         TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
8785         return WMError::WM_ERROR_NULLPTR;
8786     }
8787     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8788     auto task = [this, windowManagerAgent, type, callingPid]() {
8789         return SessionManagerAgentController::GetInstance()
8790             .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
8791     };
8792     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
8793 }
8794 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)8795 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
8796 {
8797     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
8798 }
8799 
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)8800 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
8801 {
8802     SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
8803 }
8804 
StartWindowInfoReportLoop()8805 void SceneSessionManager::StartWindowInfoReportLoop()
8806 {
8807     TLOGD(WmsLogTag::WMS_STARTUP_PAGE, "in");
8808     if (isReportTaskStart_) {
8809         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "Report is ReportTask Start");
8810         return;
8811     }
8812     auto task = [this] {
8813         WindowInfoReporter::GetInstance().ReportRecordedInfos();
8814         ReportWindowProfileInfos();
8815         isReportTaskStart_ = false;
8816         StartWindowInfoReportLoop();
8817     };
8818     int64_t delayTime = 1000 * 60 * 60; // an hour.
8819     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
8820     if (!ret) {
8821         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "failed. task is WindowInfoReport");
8822         return;
8823     }
8824     isReportTaskStart_ = true;
8825 }
8826 
InitPersistentStorage()8827 void SceneSessionManager::InitPersistentStorage()
8828 {
8829     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
8830         int32_t storageMode = -1;
8831         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
8832         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
8833             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
8834             TLOGI(WmsLogTag::DEFAULT, "init MaximizeMode as %{public}d from persistent storage", storageMode);
8835             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
8836         }
8837     }
8838 }
8839 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)8840 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
8841 {
8842     TLOGD(WmsLogTag::DEFAULT, "in.");
8843     if (!SessionPermission::IsSystemServiceCalling()) {
8844         TLOGE(WmsLogTag::DEFAULT, "Only support for system service.");
8845         return WMError::WM_ERROR_NOT_SYSTEM_APP;
8846     }
8847     auto task = [this, &infos]() {
8848         std::map<int32_t, sptr<SceneSession>>::iterator iter;
8849         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8850         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
8851             sptr<SceneSession> sceneSession = iter->second;
8852             if (sceneSession == nullptr) {
8853                 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "null scene session");
8854                 continue;
8855             }
8856             bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
8857                 sceneSession->IsVisibleForAccessibility() :
8858                 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
8859             TLOGND(WmsLogTag::WMS_ATTRIBUTE, "name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, "
8860                 "winType=%{public}d, state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
8861                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
8862                 sceneSession->GetSessionState(), isVisibleForAccessibility);
8863             if (isVisibleForAccessibility) {
8864                 FillWindowInfo(infos, iter->second);
8865             }
8866         }
8867         return WMError::WM_OK;
8868     };
8869     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
8870 }
8871 
CheckUnreliableWindowType(WindowType windowType)8872 static bool CheckUnreliableWindowType(WindowType windowType)
8873 {
8874     if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
8875         windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
8876         windowType == WindowType::WINDOW_TYPE_TOAST) {
8877         return true;
8878     }
8879     TLOGD(WmsLogTag::DEFAULT, "false, WindowType=%{public}d", windowType);
8880     return false;
8881 }
8882 
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)8883 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
8884     std::vector<sptr<UnreliableWindowInfo>>& infos)
8885 {
8886     if (sceneSession == nullptr) {
8887         TLOGW(WmsLogTag::DEFAULT, "null scene session.");
8888         return;
8889     }
8890     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
8891         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
8892         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
8893         TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
8894         return;
8895     }
8896     sptr<UnreliableWindowInfo> info = sptr<UnreliableWindowInfo>::MakeSptr();
8897     info->windowId_ = sceneSession->GetPersistentId();
8898     WSRect windowRect = sceneSession->GetSessionRect();
8899     info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
8900     info->zOrder_ = sceneSession->GetZOrder();
8901     info->floatingScale_ = sceneSession->GetFloatingScale();
8902     info->scaleX_ = sceneSession->GetScaleX();
8903     info->scaleY_ = sceneSession->GetScaleY();
8904     infos.emplace_back(info);
8905     TLOGD(WmsLogTag::WMS_MAIN, "wid=%{public}d", info->windowId_);
8906 }
8907 
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)8908 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
8909     std::vector<sptr<UnreliableWindowInfo>>& infos)
8910 {
8911     TLOGD(WmsLogTag::DEFAULT, "in.");
8912     if (!SessionPermission::IsSystemServiceCalling()) {
8913         TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
8914         return WMError::WM_ERROR_NOT_SYSTEM_APP;
8915     }
8916     auto task = [this, windowId, &infos]() {
8917         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8918         for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
8919             if (sceneSession == nullptr) {
8920                 TLOGNW(WmsLogTag::DEFAULT, "null scene session");
8921                 continue;
8922             }
8923             if (sessionId == windowId) {
8924                 TLOGNI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
8925                 FillUnreliableWindowInfo(sceneSession, infos);
8926                 continue;
8927             }
8928             if (!sceneSession->GetRSVisible()) {
8929                 TLOGND(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
8930                 continue;
8931             }
8932             TLOGND(WmsLogTag::DEFAULT, "name=%{public}s, isSystem=%{public}d, "
8933                 "persistentId=%{public}d, winType=%{public}d, state=%{public}d, visible=%{public}d",
8934                 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
8935                 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
8936             if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
8937                 TLOGI(WmsLogTag::DEFAULT, "persistentId=%{public}d, "
8938                     "WindowType=%{public}d", sessionId, sceneSession->GetWindowType());
8939                 FillUnreliableWindowInfo(sceneSession, infos);
8940             }
8941         }
8942         return WMError::WM_OK;
8943     };
8944     return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
8945 }
8946 
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)8947 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
8948 {
8949     TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d, updateType=%{public}d", persistentId, type);
8950     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8951     if (sceneSession == nullptr) {
8952         TLOGE(WmsLogTag::DEFAULT, "sceneSession nullptr!");
8953         return;
8954     }
8955     wptr<SceneSession> weakSceneSession(sceneSession);
8956     if (processingFlushUIParams_.load()) {
8957         TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
8958         auto task = [this, weakSceneSession, type]() {
8959             auto sceneSession = weakSceneSession.promote();
8960             if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8961                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8962                 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8963             }
8964         };
8965         taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
8966         return;
8967     }
8968     auto task = [this, weakSceneSession, type]() {
8969         auto sceneSession = weakSceneSession.promote();
8970         NotifyAllAccessibilityInfo();
8971         if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8972             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8973             WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8974         }
8975     };
8976     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
8977     auto notifySceneInputTask = [weakSceneSession, type]() {
8978         auto sceneSession = weakSceneSession.promote();
8979         if (sceneSession == nullptr) {
8980             return;
8981         }
8982         SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
8983     };
8984     taskScheduler_->PostAsyncTask(notifySceneInputTask, "notifySceneInputTask");
8985 }
8986 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)8987 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
8988     const sptr<SceneSession>& sceneSession)
8989 {
8990     if (sceneSession == nullptr) {
8991         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "null scene session.");
8992         return false;
8993     }
8994     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
8995         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
8996         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
8997         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter gesture window.");
8998         return false;
8999     }
9000     if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
9001         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter DragScale window.");
9002         return false;
9003     }
9004     sptr<AccessibilityWindowInfo> info = sptr<AccessibilityWindowInfo>::MakeSptr();
9005     if (sceneSession->GetSessionInfo().isSystem_) {
9006         info->wid_ = 1;
9007         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
9008     } else {
9009         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
9010     }
9011     info->uiNodeId_ = sceneSession->GetUINodeId();
9012     info->type_ = sceneSession->GetWindowType();
9013     info->mode_ = sceneSession->GetWindowMode();
9014     info->layer_ = sceneSession->GetZOrder();
9015     info->scaleVal_ = sceneSession->GetFloatingScale();
9016     info->scaleX_ = sceneSession->GetScaleX();
9017     info->scaleY_ = sceneSession->GetScaleY();
9018     info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
9019     info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
9020     info->isDecorEnable_ = sceneSession->GetSessionProperty()->IsDecorEnable();
9021     WSRect wsRect = sceneSession->GetSessionGlobalRectWithSingleHandScale(); // only accessability and mmi need global
9022     DisplayId displayId = sceneSession->GetSessionProperty()->GetDisplayId();
9023     if (!sceneSession->GetSessionInfo().isSystem_ &&
9024         PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(displayId)) {
9025         displayId = sceneSession->TransformGlobalRectToRelativeRect(wsRect);
9026     }
9027     info->displayId_ = displayId;
9028     info->focused_ = sceneSession->GetPersistentId() == GetFocusedSessionId(displayId);
9029     info->windowRect_ = { wsRect.posX_, wsRect.posY_, wsRect.width_, wsRect.height_ };
9030     infos.emplace_back(info);
9031     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, innerWid: %{public}d, nodeId: %{public}d"
9032         ", bundleName: %{public}s, displayId: %{public}" PRIu64 ", rect: %{public}s",
9033         info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str(),
9034         info->displayId_, info->windowRect_.ToString().c_str());
9035     return true;
9036 }
9037 
SelectSesssionFromMap(const uint64_t & surfaceId)9038 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
9039 {
9040     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9041     for (const auto& [_, sceneSession] : sceneSessionMap_) {
9042         if (sceneSession == nullptr) {
9043             continue;
9044         }
9045         if (sceneSession->GetSurfaceNode() == nullptr) {
9046             continue;
9047         }
9048         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
9049             return sceneSession;
9050         }
9051     }
9052     return nullptr;
9053 }
9054 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)9055 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
9056 {
9057     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "in");
9058     auto task = [this, weak = std::weak_ptr<RSOcclusionData>(occlusiontionData)]() {
9059         auto weakOcclusionData = weak.lock();
9060         if (weakOcclusionData == nullptr) {
9061             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "weak occlusionData is nullptr");
9062             return;
9063         }
9064         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
9065         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
9066         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
9067         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
9068         if (currVisibleData.size() != 0) {
9069             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
9070         }
9071         if (visibilityChangeInfos.size() != 0) {
9072             DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
9073             CacVisibleWindowNum();
9074         }
9075 
9076         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
9077         if (currDrawingContentData.size() != 0) {
9078             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
9079         }
9080         if (drawingContentChangeInfos.size() != 0) {
9081             DealwithDrawingContentChange(drawingContentChangeInfos);
9082         }
9083     };
9084     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
9085 }
9086 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)9087 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
9088     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
9089     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
9090 {
9091     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
9092     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
9093         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
9094         switch (windowLayerState) {
9095             case WINDOW_ALL_VISIBLE:
9096             case WINDOW_SEMI_VISIBLE:
9097             case WINDOW_IN_VISIBLE:
9098                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
9099                 break;
9100             case WINDOW_LAYER_DRAWING:
9101                 currDrawingContentData.emplace_back(iter->first, true);
9102                 break;
9103             case WINDOW_LAYER_NO_DRAWING:
9104                 currDrawingContentData.emplace_back(iter->first, false);
9105                 break;
9106             default:
9107                 break;
9108         }
9109     }
9110 }
9111 
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)9112 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
9113     WindowVisibilityState visibleState,
9114     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
9115     std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
9116     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9117 {
9118     if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
9119             visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9120         auto subSessions = GetSubSceneSession(session->GetWindowId());
9121         if (subSessions.empty()) {
9122             return;
9123         }
9124 
9125         RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
9126 
9127         for (const auto& subSession : subSessions) {
9128             if (subSession == nullptr) {
9129                 continue;
9130             }
9131             if (GetSessionRSVisible(subSession, currVisibleData)) {
9132                 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Update subwindow visibility for winId: %{public}d",
9133                     subSession->GetWindowId());
9134                 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
9135             }
9136         }
9137     }
9138 }
9139 
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)9140 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
9141     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9142 {
9143     bool sessionRSVisible = false;
9144     for (const auto& [surfaceId, visibleState] : currVisibleData) {
9145         sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
9146         if (visibilitySession == nullptr) {
9147             continue;
9148         }
9149         if (session->GetWindowId() == visibilitySession->GetWindowId()) {
9150             if (visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9151                 sessionRSVisible = true;
9152             }
9153             break;
9154         }
9155     }
9156     return sessionRSVisible;
9157 }
9158 
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)9159 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
9160     WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
9161     std::string& visibilityInfo)
9162 {
9163     if (session == nullptr) {
9164         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Session is invalid!");
9165         return;
9166     }
9167     session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9168     session->SetVisibilityState(visibleState);
9169     int32_t windowId = session->GetWindowId();
9170     if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
9171         session->NotifyWindowVisibility();
9172     }
9173     auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(
9174         windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType());
9175     windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
9176     windowVisibilityInfo->SetBundleName(session->GetSessionInfo().bundleName_);
9177     windowVisibilityInfo->SetAbilityName(session->GetSessionInfo().abilityName_);
9178     windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
9179     windowVisibilityInfos.emplace_back(windowVisibilityInfo);
9180 
9181     visibilityInfo +=
9182         "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
9183 }
9184 
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)9185 void SceneSessionManager::RemoveDuplicateSubSession(
9186     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
9187     std::vector<sptr<SceneSession>>& subSessions)
9188 {
9189     for (const auto& elem : visibilityChangeInfo) {
9190         uint64_t surfaceId = elem.first;
9191         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9192         if (session == nullptr) {
9193             continue;
9194         }
9195         for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
9196             auto subSession = *iterator;
9197             if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
9198                 iterator = subSessions.erase(iterator);
9199             } else {
9200                 ++iterator;
9201             }
9202         }
9203     }
9204 }
9205 
GetSubSceneSession(int32_t parentWindowId)9206 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
9207 {
9208     std::vector<sptr<SceneSession>> subSessions;
9209     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9210     for (const auto& iter : sceneSessionMap_) {
9211         auto sceneSession = iter.second;
9212         if (sceneSession == nullptr) {
9213             continue;
9214         }
9215         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9216             continue;
9217         }
9218         const auto& mainOrFloatSession = sceneSession->GetMainOrFloatSession();
9219         if (mainOrFloatSession != nullptr && mainOrFloatSession->GetWindowId() == parentWindowId) {
9220             subSessions.push_back(sceneSession);
9221         }
9222     }
9223     return subSessions;
9224 }
9225 
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)9226 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
9227     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9228 {
9229     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
9230     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
9231     uint32_t i, j;
9232     i = j = 0;
9233     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
9234         if (lastVisibleData_[i].first < currVisibleData[j].first) {
9235             if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
9236                 i++;
9237                 continue;
9238             }
9239             if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9240                 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9241             }
9242             i++;
9243         } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
9244             if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9245                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
9246             }
9247             j++;
9248         } else {
9249             if (lastVisibleData_[i].second != currVisibleData[j].second &&
9250                 !IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
9251                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
9252             }
9253             i++;
9254             j++;
9255         }
9256     }
9257     for (; i < lastVisibleData_.size(); ++i) {
9258         if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
9259             continue;
9260         }
9261         if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9262             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9263         }
9264     }
9265     for (; j < currVisibleData.size(); ++j) {
9266         if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9267             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
9268         }
9269     }
9270     lastVisibleData_ = currVisibleData;
9271     return visibilityChangeInfo;
9272 }
9273 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)9274 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
9275     visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9276 {
9277     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
9278 #ifdef MEMMGR_WINDOW_ENABLE
9279     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
9280 #endif
9281 
9282     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
9283     for (const auto& elem : visibilityChangeInfo) {
9284         uint64_t surfaceId = elem.first;
9285         WindowVisibilityState visibleState = elem.second;
9286         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
9287         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9288         if (session == nullptr) {
9289             continue;
9290         }
9291         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
9292             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
9293             if (session->GetParentSession() != nullptr &&
9294                 !session->GetParentSession()->IsSessionForeground() &&
9295                 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
9296                 continue;
9297             }
9298         }
9299         SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
9300         UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
9301 #ifdef MEMMGR_WINDOW_ENABLE
9302         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
9303             session->GetCallingUid(), isVisible));
9304 #endif
9305         CheckAndNotifyWaterMarkChangedResult();
9306     }
9307     if (windowVisibilityInfos.size() != 0) {
9308         TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
9309             visibilityInfo.c_str());
9310         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
9311     }
9312     ProcessWindowModeType();
9313 #ifdef MEMMGR_WINDOW_ENABLE
9314     if (memMgrWindowInfos.size() != 0) {
9315         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Notify memMgrWindowInfos changed start");
9316         taskScheduler_ ->AddExportTask("notifyMemMgr", [memMgrWindowInfos = std::move(memMgrWindowInfos)]() {
9317             Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
9318         });
9319     }
9320 #endif
9321 }
9322 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)9323 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
9324     drawingContentChangeInfo)
9325 {
9326     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
9327     for (const auto& [surfaceId, drawingState] : drawingContentChangeInfo) {
9328         int32_t windowId = 0;
9329         int32_t pid = 0;
9330         int32_t uid = 0;
9331         WindowType type = WindowType::APP_WINDOW_BASE;
9332         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9333         if (session == nullptr) {
9334             if (!GetSpecifiedDrawingData(surfaceId, pid, uid)) {
9335                 continue;
9336             }
9337             RemoveSpecifiedDrawingData(surfaceId);
9338         } else {
9339             windowId = session->GetWindowId();
9340             pid = session->GetCallingPid();
9341             uid = session->GetCallingUid();
9342             type = session->GetWindowType();
9343         }
9344         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(windowId, pid, uid, drawingState, type));
9345         if (openDebugTrace_) {
9346             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
9347                 "drawingState:(%d )", pid, surfaceId, drawingState);
9348         }
9349         TLOGD(WmsLogTag::DEFAULT, "drawing status changed pid:%{public}d, "
9350             "surfaceId:%{public}" PRIu64 ", drawingState:%{public}d", pid, surfaceId, drawingState);
9351     }
9352     if (windowDrawingContenInfos.size() != 0) {
9353         TLOGD(WmsLogTag::DEFAULT, "Notify WindowDrawingContenInfo changed start");
9354         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
9355     }
9356 }
9357 
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)9358 WSError SceneSessionManager::NotifyAppUseControlList(
9359     ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
9360 {
9361     TLOGI(WmsLogTag::WMS_LIFE,
9362         "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
9363         static_cast<int>(type), userId, controlList.size());
9364     if (!SessionPermission::IsSACalling()) {
9365         TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9366         return WSError::WS_ERROR_INVALID_PERMISSION;
9367     }
9368     if (type == ControlAppType::APP_LOCK &&
9369         !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
9370         TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
9371         return WSError::WS_ERROR_INVALID_PERMISSION;
9372     }
9373     if (currentUserId_ != userId) {
9374         if (currentUserId_ != DEFAULT_USERID) {
9375             TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
9376                 currentUserId_.load(), userId);
9377             return WSError::WS_ERROR_INVALID_OPERATION;
9378         }
9379         int32_t userIdByUid = GetUserIdByUid(getuid());
9380         if (userId != userIdByUid) {
9381             TLOGW(WmsLogTag::WMS_LIFE,
9382                 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
9383                 currentUserId_.load(), userId, userIdByUid);
9384             return WSError::WS_ERROR_INVALID_OPERATION;
9385         }
9386     }
9387     taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
9388         if (notifyAppUseControlListFunc_ != nullptr) {
9389             notifyAppUseControlListFunc_(type, userId, controlList);
9390         }
9391 
9392         std::vector<sptr<SceneSession>> mainSessions;
9393         for (const auto& appUseControlInfo : controlList) {
9394             GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
9395             if (mainSessions.empty()) {
9396                 continue;
9397             }
9398             SceneSession::ControlInfo controlInfo = {
9399                 .isNeedControl = appUseControlInfo.isNeedControl_,
9400                 .isControlRecentOnly = appUseControlInfo.isControlRecentOnly_
9401             };
9402             for (const auto& session : mainSessions) {
9403                 session->NotifyUpdateAppUseControl(type, controlInfo);
9404             }
9405             mainSessions.clear();
9406         }
9407     }, __func__);
9408     return WSError::WS_OK;
9409 }
9410 
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)9411 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
9412 {
9413     taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
9414         notifyAppUseControlListFunc_ = std::move(callback);
9415     }, __func__);
9416 }
9417 
GetSpecifiedDrawingData(uint64_t surfaceId,int32_t & pid,int32_t & uid)9418 bool SceneSessionManager::GetSpecifiedDrawingData(uint64_t surfaceId, int32_t& pid, int32_t& uid)
9419 {
9420     auto it = lastDrawingSessionInfoMap_.find(surfaceId);
9421     if (it != lastDrawingSessionInfoMap_.end()) {
9422         pid = it->second.pid_;
9423         uid = it->second.uid_;
9424         return true;
9425     }
9426     return false;
9427 }
9428 
RemoveSpecifiedDrawingData(uint64_t surfaceId)9429 void SceneSessionManager::RemoveSpecifiedDrawingData(uint64_t surfaceId)
9430 {
9431     auto it = lastDrawingSessionInfoMap_.find(surfaceId);
9432     if (it != lastDrawingSessionInfoMap_.end()) {
9433         lastDrawingSessionInfoMap_.erase(it);
9434     }
9435 }
9436 
GetWindowDrawingContentChangeInfo(const std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)9437 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
9438     const std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
9439 {
9440     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
9441     for (const auto& [surfaceId, isWindowDrawing] : currDrawingContentData) {
9442         int32_t pid = 0;
9443         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9444         bool isDrawingStateChanged =
9445             session == nullptr || (GetPreWindowDrawingState(surfaceId, isWindowDrawing, pid) != isWindowDrawing &&
9446                                    GetProcessDrawingState(surfaceId, pid));
9447         if (isDrawingStateChanged) {
9448             processDrawingContentChangeInfo.emplace_back(surfaceId, isWindowDrawing);
9449         }
9450     }
9451     return processDrawingContentChangeInfo;
9452 }
9453 
GetPreWindowDrawingState(uint64_t surfaceId,bool currentWindowDrawing,int32_t & pid)9454 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t surfaceId, bool currentWindowDrawing, int32_t& pid)
9455 {
9456     sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9457     if (session == nullptr) {
9458         return false;
9459     }
9460     pid = session->GetCallingPid();
9461     bool preWindowDrawing = session->GetDrawingContentState();
9462     session->SetDrawingContentState(currentWindowDrawing);
9463     UpdateWindowDrawingData(surfaceId, pid, session->GetCallingUid());
9464     return preWindowDrawing;
9465 }
9466 
UpdateWindowDrawingData(uint64_t surfaceId,int32_t pid,int32_t uid)9467 void SceneSessionManager::UpdateWindowDrawingData(uint64_t surfaceId, int32_t pid, int32_t uid)
9468 {
9469     lastDrawingSessionInfoMap_[surfaceId] = { pid, uid };
9470 }
9471 
GetProcessDrawingState(uint64_t surfaceId,int32_t pid)9472 bool SceneSessionManager::GetProcessDrawingState(uint64_t surfaceId, int32_t pid)
9473 {
9474     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9475     for (const auto& [_, sceneSession] : sceneSessionMap_) {
9476         if (sceneSession == nullptr) {
9477             continue;
9478         }
9479         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
9480             surfaceId != sceneSession->GetSurfaceNode()->GetId()) {
9481             if (sceneSession->GetDrawingContentState()) {
9482                 return false;
9483             }
9484         }
9485     }
9486     return true;
9487 }
9488 
InitWithRenderServiceAdded()9489 void SceneSessionManager::InitWithRenderServiceAdded()
9490 {
9491     auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
9492         this->WindowLayerInfoChangeCallback(occlusiontionData);
9493     };
9494     TLOGI(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback");
9495     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
9496         TLOGE(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback failed");
9497     }
9498 }
9499 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType,bool isRegularAnimation)9500 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType, bool isRegularAnimation)
9501 {
9502     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
9503         TLOGE(WmsLogTag::DEFAULT, "The input scene type is valid, scene type is %{public}d", sceneType);
9504         return WMError::WM_ERROR_INVALID_PARAM;
9505     }
9506 
9507     auto task = [this, sceneType, isRegularAnimation]() {
9508         TLOGND(WmsLogTag::WMS_PC, "Set system animated scene %{public}d.", sceneType);
9509         bool ret = rsInterface_.SetSystemAnimatedScenes(
9510             static_cast<SystemAnimatedScenes>(sceneType), isRegularAnimation);
9511         if (!ret) {
9512             TLOGNE(WmsLogTag::WMS_PC, "Set system animated scene failed.");
9513         }
9514     };
9515     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
9516     return WMError::WM_OK;
9517 }
9518 
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)9519 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
9520 {
9521     if (!SessionPermission::IsSystemCalling()) {
9522         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
9523         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9524     }
9525     if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
9526         TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
9527         return WSError::WS_ERROR_INVALID_PERMISSION;
9528     }
9529     TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
9530         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
9531     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
9532     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
9533         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
9534         WindowType::WINDOW_TYPE_APP_COMPONENT));
9535     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
9536     return WSError::WS_OK;
9537 }
9538 
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)9539 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
9540 {
9541     if (sceneSession == nullptr) {
9542         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr!");
9543         return;
9544     }
9545     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "in, wid: %{public}d, RSVisible: %{public}d, WindowMode: %{public}u",
9546         sceneSession->GetWindowId(), sceneSession->GetRSVisible(), sceneSession->GetWindowMode());
9547     if (sceneSession->GetRSVisible() || sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
9548         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
9549 #ifdef MEMMGR_WINDOW_ENABLE
9550         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
9551 #endif
9552         sceneSession->SetRSVisible(false);
9553         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9554         sceneSession->ClearExtWindowFlags();
9555         auto windowVisibilityInfo = new WindowVisibilityInfo(sceneSession->GetWindowId(),
9556             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
9557             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType());
9558         windowVisibilityInfo->SetAppIndex(sceneSession->GetSessionInfo().appIndex_);
9559         windowVisibilityInfo->SetBundleName(sceneSession->GetSessionInfo().bundleName_);
9560         windowVisibilityInfo->SetAbilityName(sceneSession->GetSessionInfo().abilityName_);
9561         windowVisibilityInfo->SetIsSystem(sceneSession->GetSessionInfo().isSystem_);
9562         windowVisibilityInfos.emplace_back(windowVisibilityInfo);
9563 #ifdef MEMMGR_WINDOW_ENABLE
9564         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
9565             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
9566 #endif
9567         TLOGD(WmsLogTag::DEFAULT, "covered status changed window:%{public}u, isVisible:%{public}d",
9568             sceneSession->GetWindowId(), sceneSession->GetRSVisible());
9569         CheckAndNotifyWaterMarkChangedResult();
9570         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
9571 #ifdef MEMMGR_WINDOW_ENABLE
9572         TLOGD(WmsLogTag::DEFAULT, "Notify memMgrWindowInfos changed start");
9573         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
9574 #endif
9575     }
9576 }
9577 
FindSessionByToken(const sptr<IRemoteObject> & token,WindowType type)9578 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token, WindowType type)
9579 {
9580     if (token == nullptr) {
9581         TLOGW(WmsLogTag::WMS_MAIN, "token is nullptr");
9582         return nullptr;
9583     }
9584     sptr<SceneSession> session = nullptr;
9585     auto cmpFunc = [token, type](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
9586         if (pair.second == nullptr) {
9587             return false;
9588         }
9589         if (pair.second->GetWindowType() == type) {
9590             return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
9591         }
9592         return false;
9593     };
9594     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9595     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
9596     if (iter != sceneSessionMap_.end()) {
9597         session = iter->second;
9598     }
9599     return session;
9600 }
9601 
FindSessionByAffinity(const std::string & affinity)9602 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(const std::string& affinity)
9603 {
9604     if (affinity.size() == 0) {
9605         TLOGI(WmsLogTag::DEFAULT, "AbilityInfo affinity is empty");
9606         return nullptr;
9607     }
9608     sptr<SceneSession> session = nullptr;
9609     auto cmpFunc = [this, &affinity](const auto& pair) {
9610         auto sceneSession = pair.second;
9611         if (sceneSession == nullptr || !CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
9612             return false;
9613         }
9614         return sceneSession->GetSessionInfo().sessionAffinity == affinity;
9615     };
9616     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9617     if (auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
9618         iter != sceneSessionMap_.end()) {
9619         session = iter->second;
9620     }
9621     return session;
9622 }
9623 
PreloadInLakeApp(const std::string & bundleName)9624 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
9625 {
9626     TLOGD(WmsLogTag::DEFAULT, "name %{public}s", bundleName.c_str());
9627     if (auto collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE)) {
9628         TLOGI(WmsLogTag::DEFAULT, "NotifyPreloadAbility: %{public}s", bundleName.c_str());
9629         collaborator->NotifyPreloadAbility(bundleName);
9630     }
9631 }
9632 
PendingSessionToForeground(const sptr<IRemoteObject> & token)9633 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
9634 {
9635     TLOGI(WmsLogTag::WMS_LIFE, "in");
9636     auto pid = IPCSkeleton::GetCallingRealPid();
9637     if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
9638         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
9639         return WSError::WS_ERROR_INVALID_PERMISSION;
9640     }
9641 
9642     return taskScheduler_->PostSyncTask([this, &token]() {
9643         if (auto session = FindSessionByToken(token)) {
9644             return session->PendingSessionToForeground();
9645         }
9646         TLOGNE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
9647         return WSError::WS_ERROR_INVALID_PARAM;
9648     }, __func__);
9649 }
9650 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)9651 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
9652     bool shouldBackToCaller)
9653 {
9654     return taskScheduler_->PostSyncTask([this, &token, shouldBackToCaller] {
9655         if (auto session = FindSessionByToken(token)) {
9656             return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
9657         }
9658         TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
9659         return WSError::WS_ERROR_INVALID_PARAM;
9660     }, __func__);
9661 }
9662 
ClearDisplayStatusBarTemporarilyFlags()9663 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
9664 {
9665     for (auto persistentId : avoidAreaListenerSessionSet_) {
9666         auto sceneSession = GetSceneSession(persistentId);
9667         if (sceneSession == nullptr) {
9668             continue;
9669         }
9670         sceneSession->SetIsDisplayStatusBarTemporarily(false);
9671     }
9672 }
9673 
GetFocusSessionToken(sptr<IRemoteObject> & token,DisplayId displayId)9674 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject>& token, DisplayId displayId)
9675 {
9676     if (!SessionPermission::IsSACalling()) {
9677         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
9678         return WSError::WS_ERROR_INVALID_PERMISSION;
9679     }
9680     return taskScheduler_->PostSyncTask([this, &token, where = __func__, displayId]() {
9681         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
9682         if (focusGroup == nullptr) {
9683             TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
9684             return WSError::WS_ERROR_INVALID_SESSION;
9685         }
9686         TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
9687             where, focusGroup->GetFocusedSessionId());
9688         if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
9689             token = sceneSession->GetAbilityToken();
9690             if (token == nullptr) {
9691                 TLOGNE(WmsLogTag::WMS_FOCUS, "token is nullptr");
9692                 return WSError::WS_ERROR_INVALID_PARAM;
9693             }
9694             return WSError::WS_OK;
9695         }
9696         return WSError::WS_ERROR_INVALID_SESSION;
9697     }, __func__);
9698 }
9699 
GetFocusSessionElement(AppExecFwk::ElementName & element,DisplayId displayId)9700 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element, DisplayId displayId)
9701 {
9702     auto pid = IPCSkeleton::GetCallingRealPid();
9703     AppExecFwk::RunningProcessInfo info;
9704     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
9705     if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
9706         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
9707         return WSError::WS_ERROR_INVALID_PERMISSION;
9708     }
9709     return taskScheduler_->PostSyncTask([this, &element, where = __func__, displayId]() {
9710         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
9711         if (focusGroup == nullptr) {
9712             TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
9713             return WSError::WS_ERROR_INVALID_SESSION;
9714         }
9715         TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
9716             where, focusGroup->GetFocusedSessionId());
9717         if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
9718             const auto& sessionInfo = sceneSession->GetSessionInfo();
9719             element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
9720                 sessionInfo.abilityName_, sessionInfo.moduleName_);
9721             return WSError::WS_OK;
9722         }
9723         return WSError::WS_ERROR_INVALID_SESSION;
9724     }, __func__);
9725 }
9726 
UpdateSessionAvoidAreaListener(int32_t persistentId,bool haveListener)9727 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t persistentId, bool haveListener)
9728 {
9729     const auto callingPid = IPCSkeleton::GetCallingRealPid();
9730     auto task = [this, persistentId, haveListener, callingPid, where = __func__]() {
9731         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d haveListener %{public}d",
9732             where, persistentId, haveListener);
9733         auto sceneSession = GetSceneSession(persistentId);
9734         if (sceneSession == nullptr) {
9735             TLOGND(WmsLogTag::WMS_IMMS, "%{public}s sceneSession is nullptr", where);
9736             return WSError::WS_DO_NOTHING;
9737         }
9738         if (callingPid != sceneSession->GetCallingPid()) {
9739             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s Permission denied, not called by the same process", where);
9740             return WSError::WS_ERROR_INVALID_PERMISSION;
9741         }
9742         if (haveListener) {
9743             avoidAreaListenerSessionSet_.insert(persistentId);
9744             UpdateAvoidArea(persistentId);
9745         } else {
9746             avoidAreaListenerSessionSet_.erase(persistentId);
9747         }
9748         return WSError::WS_OK;
9749     };
9750     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
9751 }
9752 
UpdateAvoidSessionAvoidArea(WindowType type)9753 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type)
9754 {
9755     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
9756         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
9757     AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(avoidType);
9758     rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
9759 
9760     for (auto persistentId : avoidAreaListenerSessionSet_) {
9761         auto sceneSession = GetSceneSession(persistentId);
9762         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
9763             continue;
9764         }
9765         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(avoidType);
9766         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
9767     }
9768 }
9769 
UpdateNormalSessionAvoidArea(int32_t persistentId,const sptr<SceneSession> & sceneSession,bool & needUpdate)9770 void SceneSessionManager::UpdateNormalSessionAvoidArea(
9771     int32_t persistentId, const sptr<SceneSession>& sceneSession, bool& needUpdate)
9772 {
9773     if (rootSceneSession_->GetPersistentId() == persistentId) {
9774         UpdateRootSceneSessionAvoidArea(persistentId, needUpdate);
9775         return;
9776     }
9777     if (sceneSession == nullptr) {
9778         TLOGE(WmsLogTag::WMS_IMMS, "session is nullptr, win %{public}d", persistentId);
9779         needUpdate = false;
9780         return;
9781     }
9782     if (!IsSessionVisibleForeground(sceneSession)) {
9783         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u sessionState %{public}u",
9784             persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
9785         needUpdate = false;
9786         return;
9787     }
9788     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
9789         TLOGD(WmsLogTag::WMS_IMMS,
9790             "win %{public}d not in avoidAreaListenerNodes, cannot update avoid area", persistentId);
9791         needUpdate = false;
9792         return;
9793     }
9794     sceneSession->UpdateSizeChangeReason(SizeChangeReason::AVOID_AREA_CHANGE);
9795     sceneSession->NotifyClientToUpdateRect("AvoidAreaChange", nullptr);
9796 }
9797 
UpdateRootSceneSessionAvoidArea(int32_t persistentId,bool & needUpdate)9798 void SceneSessionManager::UpdateRootSceneSessionAvoidArea(int32_t persistentId, bool& needUpdate)
9799 {
9800     using T = std::underlying_type_t<AvoidAreaType>;
9801     for (T avoidAreaType = static_cast<T>(AvoidAreaType::TYPE_START);
9802         avoidAreaType < static_cast<T>(AvoidAreaType::TYPE_END); avoidAreaType++) {
9803         AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidAreaType));
9804         if (avoidAreaType == static_cast<T>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
9805             !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
9806                 rootSceneSession_->GetSessionRect().height_)) {
9807             continue;
9808         }
9809         rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), static_cast<AvoidAreaType>(avoidAreaType));
9810     }
9811     needUpdate = true;
9812 }
9813 
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)9814 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
9815 {
9816     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
9817     auto sceneSession = GetSceneSession(windowId);
9818     if (sceneSession == nullptr) {
9819         TLOGW(WmsLogTag::WMS_EVENT, "window not exist: %{public}d", windowId);
9820         return;
9821     }
9822 
9823     TLOGI(WmsLogTag::WMS_EVENT, "Notify window:%{public}d, pid:%{public}d", windowId, pid);
9824     taskScheduler_->PostAsyncTask([weakSceneSession = wptr<SceneSession>(sceneSession), startMoving] {
9825         auto sceneSession = weakSceneSession.promote();
9826         if (sceneSession == nullptr) {
9827             TLOGNW(WmsLogTag::WMS_EVENT, "session is null");
9828             return;
9829         }
9830         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(sceneSession, startMoving);
9831     }, __func__);
9832 }
9833 
UpdateAvoidArea(int32_t persistentId)9834 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
9835 {
9836     taskScheduler_->PostAsyncTask([this, persistentId] {
9837         bool needUpdate = false;
9838         auto sceneSession = GetSceneSession(persistentId);
9839         if (sceneSession != nullptr && sceneSession->IsImmersiveType()) {
9840             UpdateAvoidSessionAvoidArea(sceneSession->GetWindowType());
9841         } else {
9842             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
9843         }
9844         if (needUpdate) {
9845             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
9846         }
9847     }, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
9848 }
9849 
UpdateGestureBackEnabled(int32_t persistentId)9850 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
9851 {
9852     auto task = [this, persistentId, where = __func__] {
9853         auto sceneSession = GetSceneSession(persistentId);
9854         if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
9855             TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable");
9856             return;
9857         }
9858         auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
9859         if (needEnableGestureBack) {
9860             gestureBackEnableWindowIdSet_.erase(persistentId);
9861         } else {
9862             gestureBackEnableWindowIdSet_.insert(persistentId);
9863         }
9864         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
9865             sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
9866             (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
9867              sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
9868             enterRecent_.load() || !sceneSession->IsFocused()) {
9869             needEnableGestureBack = true;
9870         }
9871         if (gestureNavigationEnabledChangeFunc_ != nullptr) {
9872             gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
9873                 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
9874         } else {
9875             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s callback func is null", where);
9876         }
9877     };
9878     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
9879 }
9880 
UpdateOccupiedAreaIfNeed(int32_t persistentId)9881 void SceneSessionManager::UpdateOccupiedAreaIfNeed(int32_t persistentId)
9882 {
9883     auto task = [this, persistentId]() {
9884         sptr<SceneSession> keyboardSession = nullptr;
9885         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9886         for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
9887             auto sceneSession = item->second;
9888             if (sceneSession != nullptr &&
9889                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
9890                 keyboardSession = sceneSession;
9891                 break;
9892             }
9893         }
9894         if (keyboardSession == nullptr) {
9895             TLOGNE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
9896             return;
9897         }
9898         if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
9899             return;
9900         }
9901 
9902         keyboardSession->OnCallingSessionUpdated();
9903         return;
9904     };
9905     taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
9906 }
9907 
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)9908 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
9909 {
9910     TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u",
9911         persistentId, isVisible);
9912     taskScheduler_->PostTask([this, persistentId, isVisible] {
9913         auto sceneSession = GetSceneSession(persistentId);
9914         if (sceneSession == nullptr) {
9915             TLOGNE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
9916             return;
9917         }
9918         sceneSession->SetIsStatusBarVisible(isVisible);
9919     }, __func__);
9920     return WSError::WS_OK;
9921 }
9922 
NotifyStatusBarConstantlyShow(DisplayId displayId,bool isVisible)9923 void SceneSessionManager::NotifyStatusBarConstantlyShow(DisplayId displayId, bool isVisible)
9924 {
9925     TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " isVisible %{public}u", displayId, isVisible);
9926     const char* const where = __func__;
9927     auto task = [this, displayId, isVisible] {
9928         statusBarConstantlyShowMap_[displayId] = isVisible;
9929         return WMError::WM_OK;
9930     };
9931     taskScheduler_->PostAsyncTask(task, where);
9932 }
9933 
GetStatusBarConstantlyShow(DisplayId displayId,bool & isVisible) const9934 void SceneSessionManager::GetStatusBarConstantlyShow(DisplayId displayId, bool& isVisible) const
9935 {
9936     auto it = statusBarConstantlyShowMap_.find(displayId);
9937     if (it != statusBarConstantlyShowMap_.end()) {
9938         isVisible = it->second;
9939     } else {
9940         isVisible = false;
9941     }
9942 }
9943 
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)9944 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
9945 {
9946     TLOGI(WmsLogTag::WMS_IMMS, "isVisible %{public}u "
9947         "area %{public}s, displayId %{public}" PRIu64, isVisible, barArea.ToString().c_str(), displayId);
9948     taskScheduler_->PostAsyncTask([this, isVisible, barArea, displayId, where = __func__] {
9949         bool isNeedUpdate = true;
9950         {
9951             std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
9952             isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
9953                 currAINavigationBarAreaMap_.count(displayId) == 0 ||
9954                 currAINavigationBarAreaMap_[displayId] != barArea;
9955             if (isNeedUpdate) {
9956                 isAINavigationBarVisible_ = isVisible;
9957                 currAINavigationBarAreaMap_.clear();
9958                 currAINavigationBarAreaMap_[displayId] = barArea;
9959             }
9960             if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
9961                 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s barArea should be empty if invisible", where);
9962                 currAINavigationBarAreaMap_[displayId] = WSRect();
9963             }
9964         }
9965         if (isNeedUpdate) {
9966             TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s isVisible %{public}u bar area %{public}s",
9967                 where, isVisible, barArea.ToString().c_str());
9968             for (auto persistentId : avoidAreaListenerSessionSet_) {
9969                 NotifySessionAINavigationBarChange(persistentId);
9970             }
9971         }
9972     }, __func__);
9973     return WSError::WS_OK;
9974 }
9975 
NotifySessionAINavigationBarChange(int32_t persistentId)9976 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
9977 {
9978     auto sceneSession = GetSceneSession(persistentId);
9979     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
9980         TLOGD(WmsLogTag::WMS_IMMS, "scene session is nullptr or not visible");
9981         return;
9982     }
9983     bool isLastFrameLayoutFinished = true;
9984     IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
9985     TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d layout finished %{public}d",
9986         persistentId, isLastFrameLayoutFinished);
9987     if (isLastFrameLayoutFinished) {
9988         sceneSession->UpdateAvoidArea(
9989             new AvoidArea(sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR)),
9990             AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
9991     } else {
9992         sceneSession->MarkAvoidAreaAsDirty();
9993     }
9994 }
9995 
GetAINavigationBarArea(uint64_t displayId)9996 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
9997 {
9998     std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
9999     if (currAINavigationBarAreaMap_.count(displayId) == 0) {
10000         return {};
10001     }
10002     return currAINavigationBarAreaMap_[displayId];
10003 }
10004 
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)10005 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
10006 {
10007     const auto callingPid = IPCSkeleton::GetCallingRealPid();
10008     auto task = [this, persistentId, haveListener, callingPid]() {
10009         TLOGNI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
10010             persistentId, haveListener);
10011         auto sceneSession = GetSceneSession(persistentId);
10012         if (sceneSession == nullptr) {
10013             TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
10014             return WSError::WS_DO_NOTHING;
10015         }
10016         if (callingPid != sceneSession->GetCallingPid()) {
10017             TLOGNE(WmsLogTag::WMS_EVENT, "Permission denied");
10018             return WSError::WS_ERROR_INVALID_PERMISSION;
10019         }
10020         if (haveListener) {
10021             touchOutsideListenerSessionSet_.insert(persistentId);
10022         } else {
10023             touchOutsideListenerSessionSet_.erase(persistentId);
10024         }
10025         return WSError::WS_OK;
10026     };
10027     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
10028 }
10029 
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)10030 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
10031 {
10032     const auto callingPid = IPCSkeleton::GetCallingRealPid();
10033     return taskScheduler_->PostSyncTask([this, persistentId, haveListener, callingPid]() -> WSError {
10034         TLOGNI(WmsLogTag::WMS_LIFE, "persistentId: %{public}d haveListener:%{public}d",
10035             persistentId, haveListener);
10036         auto sceneSession = GetSceneSession(persistentId);
10037         if (sceneSession == nullptr) {
10038             TLOGND(WmsLogTag::WMS_LIFE, "sceneSession is nullptr.");
10039             return WSError::WS_DO_NOTHING;
10040         }
10041         if (callingPid != sceneSession->GetCallingPid()) {
10042             TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
10043             return WSError::WS_ERROR_INVALID_PERMISSION;
10044         }
10045         if (haveListener) {
10046             windowVisibilityListenerSessionSet_.insert(persistentId);
10047             sceneSession->NotifyWindowVisibility();
10048         } else {
10049             windowVisibilityListenerSessionSet_.erase(persistentId);
10050         }
10051         return WSError::WS_OK;
10052     }, __func__);
10053 }
10054 
UpdateDarkColorModeToRS()10055 void SceneSessionManager::UpdateDarkColorModeToRS()
10056 {
10057     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
10058     if (appContext == nullptr) {
10059         TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
10060         return;
10061     }
10062     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
10063     if (config == nullptr) {
10064         TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
10065         return;
10066     }
10067     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
10068     bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
10069     bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
10070     TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d", colorMode.c_str(), ret);
10071 }
10072 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)10073 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
10074 {
10075     processVirtualPixelRatioChangeFunc_ = func;
10076     TLOGI(WmsLogTag::DEFAULT, "end");
10077 }
10078 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)10079 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
10080     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
10081 {
10082     if (displayInfo == nullptr) {
10083         TLOGE(WmsLogTag::DEFAULT, "displayInfo is nullptr.");
10084         return;
10085     }
10086     taskScheduler_->PostSyncTask([this, displayInfo, type, where = __func__]() {
10087         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
10088             type == DisplayStateChangeType::RESOLUTION_CHANGE &&
10089             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
10090             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
10091                           displayInfo->GetWidth(), displayInfo->GetHeight() };
10092             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
10093         }
10094         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10095         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10096             if (sceneSession == nullptr) {
10097                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s null scene session", where);
10098                 continue;
10099             }
10100             if (sceneSession->GetSessionProperty()->GetDisplayId() != displayInfo->GetDisplayId()) {
10101                 continue;
10102             }
10103             if (sceneSession->GetSessionInfo().isSystem_) {
10104                 continue;
10105             }
10106             if (sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
10107                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE) {
10108                 sceneSession->UpdateDensity();
10109                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "UpdateDensity name=%{public}s, persistentId=%{public}d, "
10110                     "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
10111                     sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
10112                     sceneSession->GetSessionState(), sceneSession->IsVisible());
10113             }
10114         }
10115         UpdateDisplayRegion(displayInfo);
10116         return WSError::WS_OK;
10117     }, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
10118 }
10119 
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)10120 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
10121     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
10122 {
10123     if (displayInfo == nullptr) {
10124         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr.");
10125         return;
10126     }
10127     taskScheduler_->PostSyncTask([this, displayInfo, where = __func__]() {
10128         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10129         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10130             if (sceneSession == nullptr) {
10131                 TLOGNE(WmsLogTag::DMS, "%{public}s null scene session", where);
10132                 continue;
10133             }
10134             if (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
10135                 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) {
10136                 continue;
10137             }
10138             if (NearEqual(sceneSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
10139                 NearEqual(sceneSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
10140                 sceneSession->GetRotation() != displayInfo->GetRotation()) {
10141                 sceneSession->UpdateRotationAvoidArea();
10142                 TLOGND(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
10143                     "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
10144                     sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState(),
10145                     sceneSession->IsVisible());
10146             }
10147             sceneSession->SetRotation(displayInfo->GetRotation());
10148             sceneSession->UpdateOrientation();
10149         }
10150         UpdateDisplayRegion(displayInfo);
10151         return WSError::WS_OK;
10152     }, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
10153 }
10154 
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)10155 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
10156 {
10157     if (displayInfo == nullptr) {
10158         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
10159         return;
10160     }
10161 
10162     taskScheduler_->PostAsyncTask([this, displayInfo] {
10163         ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
10164             displayInfo->GetScaleX(),
10165             displayInfo->GetScaleY(),
10166             displayInfo->GetPivotX(),
10167             displayInfo->GetPivotY(),
10168             displayInfo->GetTranslateX(),
10169             displayInfo->GetTranslateY());
10170         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
10171         FlushWindowInfoToMMI(true);
10172     }, __func__);
10173 }
10174 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)10175 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
10176     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
10177 {
10178     TLOGD(WmsLogTag::DEFAULT, "type: %{public}u", type);
10179     switch (type) {
10180         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
10181             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
10182                 displayInfo, displayInfoMap, type);
10183             break;
10184         }
10185         case DisplayStateChangeType::UPDATE_ROTATION: {
10186             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
10187                 displayInfo, displayInfoMap, type);
10188             break;
10189         }
10190         case DisplayStateChangeType::UPDATE_SCALE: {
10191             SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
10192             break;
10193         }
10194         default:
10195             return;
10196     }
10197 }
10198 
CheckIfNeedMultipleFocus(const std::string & name,const ScreenType & screenType)10199 bool CheckIfNeedMultipleFocus(const std::string& name, const ScreenType& screenType)
10200 {
10201     if (screenType == ScreenType::VIRTUAL && name == "CeliaView") {
10202         return true;
10203     }
10204     return false;
10205 }
10206 
OnScreenConnected(const sptr<ScreenSession> & screenSession)10207 void ScreenConnectionChangeListener::OnScreenConnected(const sptr<ScreenSession>& screenSession)
10208 {
10209     if (screenSession == nullptr) {
10210         TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
10211         return;
10212     }
10213     TLOGI(WmsLogTag::WMS_FOCUS, "name: %{public}s, screenId: %{public}" PRIu64 ", screenType: %{public}u",
10214           screenSession->GetName().c_str(), screenSession->GetScreenId(),
10215           screenSession->GetScreenProperty().GetScreenType());
10216     if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
10217         SceneSessionManager::GetInstance().AddFocusGroup(screenSession->GetScreenId());
10218     }
10219 }
10220 
OnScreenDisconnected(const sptr<ScreenSession> & screenSession)10221 void ScreenConnectionChangeListener::OnScreenDisconnected(const sptr<ScreenSession>& screenSession)
10222 {
10223     if (screenSession == nullptr) {
10224         TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
10225         return;
10226     }
10227     TLOGI(WmsLogTag::WMS_FOCUS, "name: %{public}s, screenId: %{public}" PRIu64 ", screenType: %{public}u",
10228           screenSession->GetName().c_str(), screenSession->GetScreenId(),
10229           screenSession->GetScreenProperty().GetScreenType());
10230     if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
10231         SceneSessionManager::GetInstance().RemoveFocusGroup(screenSession->GetScreenId());
10232     }
10233 }
10234 
OnScreenshot(DisplayId displayId)10235 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
10236 {
10237     SceneSessionManager::GetInstance().OnScreenshot(displayId);
10238 }
10239 
OnScreenshot(DisplayId displayId)10240 void SceneSessionManager::OnScreenshot(DisplayId displayId)
10241 {
10242     taskScheduler_->PostAsyncTask([this, displayId]() {
10243         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10244         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10245             if (sceneSession == nullptr) {
10246                 continue;
10247             }
10248             auto state = sceneSession->GetSessionState();
10249             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
10250                 sceneSession->NotifyScreenshot();
10251             }
10252         }
10253     }, "OnScreenshot:PID:" + std::to_string(displayId));
10254 }
10255 
ClearSession(int32_t persistentId)10256 WSError SceneSessionManager::ClearSession(int32_t persistentId)
10257 {
10258     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", persistentId);
10259     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10260         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10261         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10262     }
10263     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10264         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10265         return WSError::WS_ERROR_INVALID_PERMISSION;
10266     }
10267     taskScheduler_->PostAsyncTask([this, persistentId]() {
10268         auto sceneSession = GetSceneSession(persistentId);
10269         return ClearSession(sceneSession);
10270     }, "ClearSession:PID:" + std::to_string(persistentId));
10271     return WSError::WS_OK;
10272 }
10273 
ClearSession(sptr<SceneSession> sceneSession)10274 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
10275 {
10276     TLOGD(WmsLogTag::WMS_LIFE, "in");
10277     if (sceneSession == nullptr) {
10278         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
10279         return WSError::WS_ERROR_INVALID_SESSION;
10280     }
10281     if (!IsSessionClearable(sceneSession)) {
10282         TLOGE(WmsLogTag::WMS_LIFE, "session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
10283         return WSError::WS_ERROR_INVALID_SESSION;
10284     }
10285     const WSError errCode = sceneSession->Clear();
10286     return errCode;
10287 }
10288 
ClearAllSessions()10289 WSError SceneSessionManager::ClearAllSessions()
10290 {
10291     TLOGD(WmsLogTag::WMS_LIFE, "in");
10292     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10293         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10294         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10295     }
10296     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10297         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10298         return WSError::WS_ERROR_INVALID_PERMISSION;
10299     }
10300     auto task = [this]() {
10301         std::vector<sptr<SceneSession>> sessionVector;
10302         GetAllClearableSessions(sessionVector);
10303         for (uint32_t i = 0; i < sessionVector.size(); i++) {
10304             ClearSession(sessionVector[i]);
10305         }
10306         return WSError::WS_OK;
10307     };
10308     taskScheduler_->PostAsyncTask(task, __func__);
10309     return WSError::WS_OK;
10310 }
10311 
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)10312 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
10313 {
10314     TLOGD(WmsLogTag::WMS_LIFE, "in");
10315     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10316     for (const auto& [_, sceneSession] : sceneSessionMap_) {
10317         if (IsSessionClearable(sceneSession)) {
10318             sessionVector.push_back(sceneSession);
10319         }
10320     }
10321 }
10322 
LockSession(int32_t sessionId)10323 WSError SceneSessionManager::LockSession(int32_t sessionId)
10324 {
10325     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
10326     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10327         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
10328         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10329     }
10330     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10331         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10332         return WSError::WS_ERROR_INVALID_PERMISSION;
10333     }
10334     const char* const where = __func__;
10335     auto task = [this, sessionId, where]() {
10336         auto sceneSession = GetSceneSession(sessionId);
10337         if (sceneSession == nullptr) {
10338             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s cannot find session, id: %{public}d", where, sessionId);
10339             return WSError::WS_ERROR_INVALID_PARAM;
10340         }
10341         sceneSession->SetSessionInfoLockedState(true);
10342         return WSError::WS_OK;
10343     };
10344     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
10345 }
10346 
UnlockSession(int32_t sessionId)10347 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
10348 {
10349     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
10350     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10351         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
10352         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10353     }
10354     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10355         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10356         return WSError::WS_ERROR_INVALID_PERMISSION;
10357     }
10358     const char* const where = __func__;
10359     auto task = [this, sessionId, where]() {
10360         auto sceneSession = GetSceneSession(sessionId);
10361         if (sceneSession == nullptr) {
10362             TLOGNE(WmsLogTag::DEFAULT, "%{public}s cannot find session, id: %{public}d", where, sessionId);
10363             return WSError::WS_ERROR_INVALID_PARAM;
10364         }
10365         sceneSession->SetSessionInfoLockedState(false);
10366         return WSError::WS_OK;
10367     };
10368     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
10369 }
10370 
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)10371 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
10372 {
10373     TLOGI(WmsLogTag::WMS_LIFE, "in");
10374     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10375         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10376         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10377     }
10378     if (!SessionPermission::VerifySessionPermission()) {
10379         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10380         return WSError::WS_ERROR_INVALID_PERMISSION;
10381     }
10382 
10383     return WSError::WS_OK;
10384 }
10385 
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)10386 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
10387     std::vector<int32_t>& result)
10388 {
10389     TLOGI(WmsLogTag::WMS_LIFE, "in");
10390     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10391         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10392         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10393     }
10394     if (!SessionPermission::VerifySessionPermission()) {
10395         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10396         return WSError::WS_ERROR_INVALID_PERMISSION;
10397     }
10398 
10399     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
10400     return WSError::WS_OK;
10401 }
10402 
IsSessionClearable(sptr<SceneSession> sceneSession)10403 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> sceneSession)
10404 {
10405     if (sceneSession == nullptr) {
10406         TLOGI(WmsLogTag::WMS_MAIN, "sceneSession is nullptr");
10407         return false;
10408     }
10409     const auto& sessionInfo = sceneSession->GetSessionInfo();
10410     if (sessionInfo.abilityInfo == nullptr) {
10411         TLOGI(WmsLogTag::WMS_MAIN, "sceneSession abilityInfo is nullptr");
10412         return false;
10413     }
10414     if (sessionInfo.abilityInfo->excludeFromMissions && !sceneSession->IsAnco()) {
10415         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is excludeFromMissions", sceneSession->GetPersistentId());
10416         return false;
10417     }
10418     if (sessionInfo.abilityInfo->unclearableMission) {
10419         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is unclearable", sceneSession->GetPersistentId());
10420         return false;
10421     }
10422     if (sessionInfo.isSystem_) {
10423         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is system app", sceneSession->GetPersistentId());
10424         return false;
10425     }
10426     if (sessionInfo.lockedState) {
10427         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is in lockedState", sceneSession->GetPersistentId());
10428         return false;
10429     }
10430 
10431     return true;
10432 }
10433 
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)10434 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
10435     const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
10436 {
10437     TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
10438     auto isSaCall = SessionPermission::IsSACalling();
10439     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10440         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
10441         return WSError::WS_ERROR_INVALID_PERMISSION;
10442     }
10443     if (!CheckCollaboratorType(type)) {
10444         TLOGW(WmsLogTag::DEFAULT, "collaborator register failed, invalid type.");
10445         return WSError::WS_ERROR_INVALID_TYPE;
10446     }
10447     if (impl == nullptr) {
10448         TLOGE(WmsLogTag::DEFAULT, "Collaborator is nullptr");
10449         return WSError::WS_ERROR_NULLPTR;
10450     }
10451     if (impl->AsObject() == nullptr || !impl->AsObject()->AddDeathRecipient(collaboratorDeathRecipient_)) {
10452         TLOGE(WmsLogTag::DEFAULT, "Failed to add collaborator death recipient");
10453         return WSError::WS_ERROR_IPC_FAILED;
10454     }
10455     {
10456         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
10457         collaboratorMap_[type] = impl;
10458     }
10459     auto task = [this] {
10460         if (abilityManagerCollaboratorRegisteredFunc_) {
10461             abilityManagerCollaboratorRegisteredFunc_();
10462         }
10463     };
10464     taskScheduler_->PostTask(task, __func__);
10465     return WSError::WS_OK;
10466 }
10467 
UnregisterIAbilityManagerCollaborator(int32_t type)10468 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
10469 {
10470     TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
10471     auto isSaCall = SessionPermission::IsSACalling();
10472     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10473         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
10474         return WSError::WS_ERROR_INVALID_PERMISSION;
10475     }
10476     if (!CheckCollaboratorType(type)) {
10477         TLOGE(WmsLogTag::DEFAULT, "collaborator unregister failed, invalid type.");
10478         return WSError::WS_ERROR_INVALID_TYPE;
10479     }
10480     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(type);
10481     if (collaborator != nullptr && collaborator->AsObject() != nullptr) {
10482         TLOGI(WmsLogTag::DEFAULT, "Remove collaborator death recipient");
10483         collaborator->AsObject()->RemoveDeathRecipient(collaboratorDeathRecipient_);
10484     }
10485     {
10486         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
10487         collaboratorMap_.erase(type);
10488     }
10489     return WSError::WS_OK;
10490 }
10491 
ClearAllCollaboratorSessions()10492 void SceneSessionManager::ClearAllCollaboratorSessions()
10493 {
10494     TLOGI(WmsLogTag::WMS_MAIN, "in");
10495     std::vector<sptr<SceneSession>> collaboratorSessions;
10496     {
10497         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10498         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10499             if (sceneSession != nullptr && CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
10500                 collaboratorSessions.push_back(sceneSession);
10501             }
10502         }
10503     }
10504     for (const auto& sceneSession : collaboratorSessions) {
10505         sceneSession->Clear();
10506     }
10507 }
10508 
CheckCollaboratorType(int32_t type)10509 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
10510 {
10511     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
10512         TLOGD(WmsLogTag::WMS_MAIN, "type is invalid");
10513         return false;
10514     }
10515     return true;
10516 }
10517 
CheckIfReuseSession(SessionInfo & sessionInfo)10518 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
10519 {
10520     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
10521         sessionInfo.moduleName_);
10522     if (abilityInfo == nullptr) {
10523         TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
10524         return BrokerStates::BROKER_UNKOWN;
10525     }
10526     sessionInfo.abilityInfo = abilityInfo;
10527     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
10528     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
10529         collaboratorType = CollaboratorType::RESERVE_TYPE;
10530     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
10531         collaboratorType = CollaboratorType::OTHERS_TYPE;
10532     }
10533     if (!CheckCollaboratorType(collaboratorType)) {
10534         TLOGW(WmsLogTag::DEFAULT, "checked not collaborator!");
10535         return BrokerStates::BROKER_UNKOWN;
10536     }
10537     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
10538     sessionInfo.collaboratorType_ = collaboratorType;
10539     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
10540     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
10541         TLOGI(WmsLogTag::DEFAULT, "FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
10542         sessionInfo.reuse = true;
10543     } else {
10544         sessionInfo.reuse = false;
10545     }
10546     TLOGI(WmsLogTag::DEFAULT, "end: affinity %{public}s type %{public}d reuse %{public}d",
10547         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
10548     return resultValue;
10549 }
10550 
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)10551 BrokerStates SceneSessionManager::NotifyStartAbility(
10552     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
10553 {
10554     TLOGI(WmsLogTag::WMS_LIFE, "type %{public}d id %{public}d", collaboratorType, persistentId);
10555     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
10556     if (collaborator == nullptr) {
10557         return BrokerStates::BROKER_UNKOWN;
10558     }
10559     if (sessionInfo.want == nullptr) {
10560         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo.want is nullptr, init");
10561         sessionInfo.want = std::make_shared<AAFwk::Want>();
10562         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
10563             sessionInfo.moduleName_);
10564     }
10565     auto accessTokenIDEx = sessionInfo.callingTokenId_;
10566     if (collaborator != nullptr) {
10567         containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
10568             std::chrono::system_clock::now().time_since_epoch()).count();
10569 
10570         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
10571         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
10572             TLOGI(WmsLogTag::WMS_LIFE, "want affinity exit %{public}s.", affinity.c_str());
10573             return BrokerStates::BROKER_UNKOWN;
10574         }
10575         sessionInfo.want->SetParam("oh_persistentId", persistentId);
10576         std::shared_ptr<int32_t> ret = std::make_shared<int32_t>(0);
10577         std::shared_ptr<AAFwk::Want> notifyWant = std::make_shared<AAFwk::Want>(*(sessionInfo.want));
10578         bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([this, collaborator, accessTokenIDEx,
10579             notifyWant, abilityInfo = sessionInfo.abilityInfo, ret] {
10580             auto result = collaborator->NotifyStartAbility(*abilityInfo, currentUserId_, *notifyWant,
10581                 static_cast<uint64_t>(accessTokenIDEx));
10582             *ret = static_cast<int32_t>(result);
10583         }, NOTIFY_START_ABILITY_TIMEOUT);
10584 
10585         if (isTimeout) {
10586             TLOGE(WmsLogTag::WMS_LIFE, "notify start ability timeout, id: %{public}d", persistentId);
10587             return BrokerStates::BROKER_NOT_START;
10588         }
10589         *(sessionInfo.want) = *notifyWant;
10590         TLOGI(WmsLogTag::WMS_LIFE, "collaborator ret: %{public}d", *ret);
10591         if (*ret == 0) {
10592             return BrokerStates::BROKER_STARTED;
10593         } else {
10594             return BrokerStates::BROKER_NOT_START;
10595         }
10596     }
10597     return BrokerStates::BROKER_UNKOWN;
10598 }
10599 
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)10600 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
10601 {
10602     if (sceneSession == nullptr) {
10603         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
10604         return;
10605     }
10606     if (sessionInfo.want == nullptr) {
10607         TLOGI(WmsLogTag::DEFAULT, "sessionInfo.want is nullptr");
10608         return;
10609     }
10610     if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
10611         auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
10612         abilitySessionInfo->want = *(sessionInfo.want);
10613         int32_t missionId = abilitySessionInfo->persistentId;
10614         std::string bundleName = sessionInfo.bundleName_;
10615         int64_t timestamp = containerStartAbilityTime_;
10616         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
10617         TLOGI(WmsLogTag::DEFAULT, "call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
10618             missionId, bundleName.c_str());
10619         collaborator->NotifyMissionCreated(abilitySessionInfo);
10620     }
10621 }
10622 
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)10623 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
10624     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
10625 {
10626     TLOGD(WmsLogTag::DEFAULT, "type: %{public}d", collaboratorType);
10627     if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
10628         TLOGI(WmsLogTag::DEFAULT, "called");
10629         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
10630     }
10631 }
10632 
10633 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)10634 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
10635 {
10636     TLOGD(WmsLogTag::DEFAULT, "in");
10637     if (sceneSession == nullptr) {
10638         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
10639         return;
10640     }
10641     if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
10642         TLOGI(WmsLogTag::DEFAULT, "called UpdateMissionInfo");
10643         auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
10644         collaborator->UpdateMissionInfo(abilitySessionInfo);
10645     }
10646 }
10647 
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)10648 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
10649 {
10650     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
10651     if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
10652         TLOGI(WmsLogTag::DEFAULT, "called %{public}d", persistentId);
10653         collaborator->NotifyMoveMissionToForeground(persistentId);
10654     }
10655 }
10656 
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)10657 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
10658 {
10659     TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
10660     if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
10661         const char* const where = __func__;
10662         ffrtQueueHelper_->SubmitTask([collaborator, persistentId, where] {
10663             int32_t ret = collaborator->NotifyClearMission(persistentId);
10664             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s called clear mission ret: %{public}d, persistent id: %{public}d",
10665                 where, ret, persistentId);
10666         });
10667     }
10668 }
10669 
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)10670 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
10671 {
10672     if (sceneSession == nullptr) {
10673         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
10674         return false;
10675     }
10676     std::string sessionAffinity;
10677     TLOGI(WmsLogTag::WMS_LIFE, "call");
10678     if (sceneSession->GetSessionInfo().want != nullptr) {
10679         sessionAffinity = sceneSession->GetSessionInfo().want
10680             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
10681     }
10682     if (sessionAffinity.empty()) {
10683         TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
10684         BrokerStates notifyReturn = NotifyStartAbility(
10685             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
10686         if (notifyReturn == BrokerStates::BROKER_NOT_START) {
10687             TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
10688             return false;
10689         }
10690     }
10691     if (sceneSession->GetSessionInfo().want != nullptr) {
10692         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
10693             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
10694         TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
10695             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
10696             sceneSession->GetSessionInfo().sessionAffinity.c_str());
10697     } else {
10698         TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
10699     }
10700     return true;
10701 }
10702 
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)10703 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
10704 {
10705     if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
10706         return false;
10707     }
10708     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
10709     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
10710     return true;
10711 }
10712 
AddWindowDragHotArea(DisplayId displayId,uint32_t type,WSRect & area)10713 void SceneSessionManager::AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)
10714 {
10715     TLOGI(WmsLogTag::WMS_LAYOUT, "displayId: %{public}" PRIu64 ", "
10716         "type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
10717         "height: %{public}d", displayId, type, area.posX_, area.posY_, area.width_, area.height_);
10718     SceneSession::AddOrUpdateWindowDragHotArea(displayId, type, area);
10719 }
10720 
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)10721 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
10722 {
10723     auto task = [this, persistentId, isMaximize]() {
10724         TLOGND(WmsLogTag::WMS_PC, "update maximize mode, id: %{public}d, isMaximize: %{public}d",
10725             persistentId, isMaximize);
10726         auto sceneSession = GetSceneSession(persistentId);
10727         if (sceneSession == nullptr) {
10728             TLOGNE(WmsLogTag::WMS_PC, "could not find window, persistentId:%{public}d", persistentId);
10729             return WSError::WS_ERROR_INVALID_WINDOW;
10730         }
10731         sceneSession->UpdateMaximizeMode(isMaximize);
10732         return WSError::WS_OK;
10733     };
10734     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
10735     return WSError::WS_OK;
10736 }
10737 
GetIsLayoutFullScreen(bool & isLayoutFullScreen)10738 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
10739 {
10740     auto task = [this, &isLayoutFullScreen]() {
10741         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10742         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10743             if (sceneSession == nullptr) {
10744                 TLOGNE(WmsLogTag::WMS_IMMS, "Session is nullptr");
10745                 continue;
10746             }
10747             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10748                 continue;
10749             }
10750             auto state = sceneSession->GetSessionState();
10751             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
10752                 continue;
10753             }
10754             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
10755                 continue;
10756             }
10757             isLayoutFullScreen = sceneSession->GetSessionProperty()->IsLayoutFullScreen();
10758             if (isLayoutFullScreen) {
10759                 TLOGND(WmsLogTag::WMS_IMMS, "Current window is immersive, persistentId:%{public}d",
10760                     sceneSession->GetPersistentId());
10761                 return WSError::WS_OK;
10762             } else {
10763                 TLOGND(WmsLogTag::WMS_IMMS, "Current window is not immersive, persistentId:%{public}d",
10764                     sceneSession->GetPersistentId());
10765             }
10766         }
10767         TLOGND(WmsLogTag::WMS_IMMS, "No immersive window");
10768         return WSError::WS_OK;
10769     };
10770 
10771     taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
10772     return WSError::WS_OK;
10773 }
10774 
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)10775 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
10776 {
10777     auto sceneSession = GetSceneSession(persistentId);
10778     if (!sceneSession) {
10779         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
10780         return WSError::WS_ERROR_INVALID_WINDOW;
10781     }
10782     auto fromScreenId = sceneSession->GetSessionInfo().screenId_;
10783     sceneSession->SetScreenId(screenId);
10784     sceneSession->GetSessionProperty()->SetDisplayId(screenId);
10785     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, move display %{public}" PRIu64 " from %{public}" PRIu64,
10786         sceneSession->GetPersistentId(), screenId, fromScreenId);
10787     NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
10788     sceneSession->NotifyDisplayMove(fromScreenId, screenId);
10789     sceneSession->UpdateDensity();
10790 
10791     // Find keyboard session.
10792     const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
10793     for (const auto& keyboardSession : keyboardSessionVec) {
10794         if (!keyboardSession) {
10795             continue;
10796         }
10797         TLOGD(WmsLogTag::WMS_KEYBOARD, "isSystemKeyboard: %{public}d, callingSessionId: %{public}d",
10798             keyboardSession->IsSystemKeyboard(), keyboardSession->GetCallingSessionId());
10799         if (!keyboardSession->IsSystemKeyboard() &&
10800             static_cast<int32_t>(keyboardSession->GetCallingSessionId()) == persistentId) {
10801             CallingWindowInfo callingWindowInfo(persistentId, sceneSession->GetCallingPid(), screenId, GetUserIdByUid(getuid()));
10802             SessionManagerAgentController::GetInstance().NotifyCallingWindowDisplayChanged(callingWindowInfo);
10803             break;
10804         }
10805     }
10806     return WSError::WS_OK;
10807 }
10808 
NotifyStackEmpty(int32_t persistentId)10809 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
10810 {
10811     TLOGI(WmsLogTag::WMS_LIFE, "persistentId %{public}d", persistentId);
10812     auto task = [this, persistentId]() {
10813         auto sceneSession = GetSceneSession(persistentId);
10814         if (!sceneSession) {
10815             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
10816             return WSError::WS_ERROR_INVALID_WINDOW;
10817         }
10818         NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::STACK_EMPTY);
10819         return WSError::WS_OK;
10820     };
10821     taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
10822     return WSError::WS_OK;
10823 }
10824 
OnImmersiveStateChange(ScreenId screenId,bool & immersive)10825 void DisplayChangeListener::OnImmersiveStateChange(ScreenId screenId, bool& immersive)
10826 {
10827     immersive = SceneSessionManager::GetInstance().GetImmersiveState(screenId);
10828 }
10829 
GetImmersiveState(ScreenId screenId)10830 bool SceneSessionManager::GetImmersiveState(ScreenId screenId)
10831 {
10832     return taskScheduler_->PostSyncTask([this, screenId, where = __func__] {
10833         bool isPcOrPadFreeMultiWindowMode = false;
10834         IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
10835         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10836         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10837             if (sceneSession == nullptr) {
10838                 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
10839                 continue;
10840             }
10841             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10842                 continue;
10843             }
10844             auto state = sceneSession->GetSessionState();
10845             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
10846                 continue;
10847             }
10848             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
10849                 continue;
10850             }
10851             if (sceneSession->GetSessionProperty()->GetDisplayId() != screenId) {
10852                 continue;
10853             }
10854             if (isPcOrPadFreeMultiWindowMode) {
10855                 if (sceneSession->IsLayoutFullScreen()) {
10856                     return true;
10857                 }
10858                 continue;
10859             }
10860             auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
10861             if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
10862                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
10863                     sceneSession->GetPersistentId());
10864                 return true;
10865             } else {
10866                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
10867                     sceneSession->GetPersistentId());
10868                 break;
10869             }
10870         }
10871         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
10872         return false;
10873     }, __func__);
10874 }
10875 
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)10876 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
10877     bool withAnimation)
10878 {
10879     session->NotifySessionForeground(reason, withAnimation);
10880 }
10881 
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)10882 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
10883     bool withAnimation, bool isFromInnerkits)
10884 {
10885     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
10886 }
10887 
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)10888 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
10889 {
10890     auto sceneSession = GetSceneSession(persistentId);
10891     if (sceneSession == nullptr) {
10892         TLOGE(WmsLogTag::DEFAULT, "could not find window, persistentId:%{public}d", persistentId);
10893         return WSError::WS_ERROR_INVALID_WINDOW;
10894     }
10895     return sceneSession->UpdateTitleInTargetPos(isShow, height);
10896 }
10897 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)10898 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
10899 {
10900     TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted");
10901     if (debugInfos.empty()) {
10902         TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted debugInfos is empty");
10903         return;
10904     }
10905 }
10906 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)10907 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
10908 {
10909     TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped");
10910     if (debugInfos.empty()) {
10911         TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped debugInfos is empty");
10912         return;
10913     }
10914 }
10915 
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)10916 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
10917 {
10918     if (!Session::IsScbCoreEnabled()) {
10919         return;
10920     }
10921     if (onFlushUIParamsFunc_ != nullptr) {
10922         onFlushUIParamsFunc_();
10923     }
10924     taskScheduler_->PostAsyncTask([this, screenId, uiParams = std::move(uiParams)]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
10925         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
10926         TLOGND(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
10927         {
10928             std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
10929             nextFlushCompletedCV_.notify_all();
10930         }
10931         std::vector<uint32_t> startingAppZOrderList;
10932         processingFlushUIParams_.store(true);
10933         {
10934             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10935             for (const auto& [_, sceneSession] : sceneSessionMap_) {
10936                 if (sceneSession == nullptr) {
10937                     continue;
10938                 }
10939                 if (sceneSession->GetSessionInfo().screenId_ != screenId) {
10940                     continue;
10941                 }
10942                 if (auto iter = uiParams.find(sceneSession->GetPersistentId()); iter != uiParams.end()) {
10943                     if ((systemConfig_.IsPhoneWindow() ||
10944                          (systemConfig_.IsPadWindow() && !systemConfig_.IsFreeMultiWindowMode())) &&
10945                         sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
10946                         startingAppZOrderList.push_back(iter->second.zOrder_);
10947                         sceneSession->SetStartingBeforeVisible(false);
10948                     }
10949                     sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
10950                 } else {
10951                     sessionMapDirty_ |= sceneSession->UpdateUIParam();
10952                 }
10953             }
10954         }
10955         processingFlushUIParams_.store(false);
10956 
10957         // post process if dirty
10958         if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
10959             static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
10960             TLOGND(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
10961             for (const auto& item : uiParams) {
10962                 TLOGND(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f,"
10963                     " transY:%{public}f, needSync:%{public}d, interactive:%{public}d", item.first, item.second.zOrder_,
10964                     item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
10965                     item.second.needSync_, item.second.interactive_);
10966             }
10967             ProcessUpdateLastFocusedAppId(startingAppZOrderList);
10968             ProcessFocusZOrderChange(sessionMapDirty_);
10969             PostProcessFocus();
10970             PostProcessProperty(sessionMapDirty_);
10971             NotifyAllAccessibilityInfo();
10972             AnomalyDetection::SceneZOrderCheckProcess();
10973         } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
10974             PostProcessProperty(sessionMapDirty_);
10975         }
10976         FlushWindowInfoToMMI();
10977         sessionMapDirty_ = 0;
10978         {
10979             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10980             for (const auto& [_, sceneSession] : sceneSessionMap_) {
10981                 if (sceneSession == nullptr) {
10982                     continue;
10983                 }
10984                 sceneSession->ResetSizeChangeReasonIfDirty();
10985                 sceneSession->ResetDirtyFlags();
10986                 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10987                     sceneSession->SetUIStateDirty(false);
10988                 }
10989             }
10990         }
10991     }, __func__);
10992 }
10993 
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)10994 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
10995 {
10996     auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
10997     if (focusGroup == nullptr) {
10998         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
10999         return;
11000     }
11001     auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
11002     TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu",
11003         lastFocusedAppSessionId, zOrderList.size());
11004     if (lastFocusedAppSessionId == INVALID_SESSION_ID || zOrderList.empty()) {
11005         return;
11006     }
11007     auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId);
11008     if (lastFocusedAppSession == nullptr) {
11009         return;
11010     }
11011     uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
11012     auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
11013         return zOrder > lastFocusedAppZOrder;
11014     });
11015     if (it != zOrderList.end()) {
11016         TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
11017         focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
11018     }
11019 }
11020 
ProcessFocusZOrderChange(uint32_t dirty)11021 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
11022 {
11023     if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
11024         return;
11025     }
11026     if (!systemConfig_.IsPhoneWindow() && !systemConfig_.IsPadWindow()) {
11027         return;
11028     }
11029     TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
11030     auto focusedSessionId = GetFocusedSessionId(DEFAULT_DISPLAY_ID);
11031     auto focusedSession = GetSceneSession(focusedSessionId);
11032     // only when it's from a high zOrder to a low zOrder
11033     if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
11034         focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
11035         return;
11036     }
11037     auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
11038     if (voiceInteractionSession == nullptr) {
11039         return;
11040     }
11041     TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
11042           "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
11043           voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
11044     if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
11045         focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
11046         return;
11047     }
11048     RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
11049 }
11050 
PostProcessFocus()11051 void SceneSessionManager::PostProcessFocus()
11052 {
11053     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
11054     // priority process focus requests from top to bottom
11055     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
11056     {
11057         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11058         for (auto& iter : sceneSessionMap_) {
11059             auto session = iter.second;
11060             if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
11061                 continue;
11062             }
11063             processingSessions.push_back(iter);
11064         }
11065     }
11066     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
11067         bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
11068             !rhs.second->GetPostProcessFocusState().isFocused_;
11069         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
11070         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
11071         return focusCmp || lhsZOrder > rhsZOrder;
11072     };
11073     std::sort(processingSessions.begin(), processingSessions.end(), cmp);
11074 
11075     // only change focus one time
11076     std::unordered_set<DisplayId> focusChangedSet;
11077     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
11078         auto session = iter->second;
11079         if (session == nullptr) {
11080             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
11081             continue;
11082         }
11083         auto displayId = session->GetSessionProperty()->GetDisplayId();
11084         auto displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
11085         TLOGD(WmsLogTag::WMS_PIPELINE,
11086             "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
11087             session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
11088             session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
11089         if (focusChangedSet.find(displayGroupId) != focusChangedSet.end()) {
11090             session->ResetPostProcessFocusState();
11091             continue;
11092         }
11093         if (!session->IsFocusedOnShow() &&
11094             (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP ||
11095              session->GetPostProcessFocusState().reason_ == FocusChangeReason::FOREGROUND)) {
11096             if (IsSessionVisibleForeground(session)) {
11097                 session->SetFocusedOnShow(true);
11098             }
11099             session->ResetPostProcessFocusState();
11100             continue;
11101         }
11102 
11103         WSError ret = WSError::WS_DO_NOTHING;
11104         if (session->GetPostProcessFocusState().isFocused_) {
11105             if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
11106                 ret = RequestSessionFocusImmediately(session->GetPersistentId());
11107             } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::RECENT) {
11108                 ret = RequestSessionFocus(session->GetPersistentId(),
11109                                           session->GetPostProcessFocusState().byForeground_,
11110                                           session->GetPostProcessFocusState().reason_);
11111             } else {
11112                 ret = RequestSessionFocus(session->GetPersistentId(), true,
11113                                           session->GetPostProcessFocusState().reason_);
11114             }
11115         } else {
11116             ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
11117         }
11118         session->ResetPostProcessFocusState();
11119         // if succeed then end process
11120         if (ret == WSError::WS_OK) {
11121             focusChangedSet.insert(displayGroupId);
11122         }
11123     }
11124 }
11125 
PostProcessProperty(uint32_t dirty)11126 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
11127 {
11128     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
11129     if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
11130         // only trigger update avoid area
11131         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11132         for (auto& iter : sceneSessionMap_) {
11133             auto session = iter.second;
11134             if (session == nullptr) {
11135                 continue;
11136             }
11137             session->PostProcessNotifyAvoidArea();
11138         }
11139         return;
11140     }
11141 
11142     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
11143     {
11144         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11145         for (auto& iter : sceneSessionMap_) {
11146             auto session = iter.second;
11147             if (session == nullptr || !session->GetPostProcessProperty()) {
11148                 continue;
11149             }
11150             processingSessions.push_back(iter);
11151         }
11152     }
11153 
11154     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
11155         auto session = iter->second;
11156         if (session == nullptr) {
11157             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
11158             continue;
11159         }
11160         TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
11161         UpdateForceHideState(session, session->GetSessionProperty(), true);
11162         HandleKeepScreenOn(session, session->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX, session->keepScreenLock_);
11163         HandleKeepScreenOn(session, session->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
11164                            session->viewKeepScreenLock_);
11165         UpdatePrivateStateAndNotify(session->GetPersistentId());
11166         if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
11167             ProcessSubSessionForeground(session);
11168         }
11169         session->SetPostProcessProperty(false);
11170     }
11171 
11172     // update avoid area
11173     {
11174         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11175         for (auto& iter : sceneSessionMap_) {
11176             auto session = iter.second;
11177             if (session == nullptr) {
11178                 continue;
11179             }
11180             session->PostProcessNotifyAvoidArea();
11181         }
11182     }
11183 }
11184 
11185 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)11186 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
11187 {
11188     TLOGI(WmsLogTag::WMS_HIERARCHY, "id %{public}d", persistentId);
11189     auto isSaCall = SessionPermission::IsSACalling();
11190     if (!isSaCall) {
11191         TLOGE(WmsLogTag::WMS_HIERARCHY, "The interface only support for sa call");
11192         return WSError::WS_ERROR_INVALID_PERMISSION;
11193     }
11194     auto task = [this, persistentId]() {
11195         auto sceneSession = GetSceneSession(persistentId);
11196         if (sceneSession == nullptr) {
11197             TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is nullptr");
11198             return WSError::WS_ERROR_INVALID_SESSION;
11199         }
11200         if (!IsSessionVisibleForeground(sceneSession)) {
11201             TLOGND(WmsLogTag::WMS_HIERARCHY, "session is not visible!");
11202             return WSError::WS_DO_NOTHING;
11203         }
11204         FocusChangeReason reason = FocusChangeReason::MOVE_UP;
11205         RequestSessionFocus(persistentId, true, reason);
11206         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
11207             sceneSession->RaiseToAppTop();
11208         }
11209         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
11210             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
11211             TLOGND(WmsLogTag::WMS_HIERARCHY, "parent session id: %{public}d", sceneSession->GetParentPersistentId());
11212             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
11213         }
11214         if (sceneSession == nullptr) {
11215             TLOGNE(WmsLogTag::WMS_HIERARCHY, "parent session is nullptr");
11216             return WSError::WS_ERROR_INVALID_SESSION;
11217         }
11218         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
11219             sceneSession->NotifyClick(true, false);
11220             return WSError::WS_OK;
11221         } else {
11222             TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is not app main window!");
11223             return WSError::WS_ERROR_INVALID_SESSION;
11224         }
11225     };
11226     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
11227     return WSError::WS_OK;
11228 }
11229 
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)11230 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
11231 {
11232     TLOGI(WmsLogTag::WMS_FOCUS, "from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
11233     sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
11234     if (sourceSession == nullptr) {
11235         TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr, id: %{public}d", sourcePersistentId);
11236         return WSError::WS_ERROR_INVALID_SESSION;
11237     }
11238     auto displayId = sourceSession->GetSessionProperty()->GetDisplayId();
11239     auto focusedSessionId = GetFocusedSessionId(displayId);
11240     if (sourcePersistentId != focusedSessionId) {
11241         TLOGE(WmsLogTag::WMS_FOCUS, "source session need be focused, focusedSessionId: %{public}d", focusedSessionId);
11242         return WSError::WS_ERROR_INVALID_OPERATION;
11243     }
11244     if (targetPersistentId == focusedSessionId) {
11245         TLOGE(WmsLogTag::WMS_FOCUS, "target session has been focused, focusedSessionId: %{public}d", focusedSessionId);
11246         return WSError::WS_DO_NOTHING;
11247     }
11248     WSError ret = GetAppMainSceneSession(sourcePersistentId, sourceSession);
11249     if (ret != WSError::WS_OK) {
11250         return ret;
11251     }
11252     sptr<SceneSession> targetSession = nullptr;
11253     ret = GetAppMainSceneSession(targetPersistentId, targetSession);
11254     if (ret != WSError::WS_OK) {
11255         return ret;
11256     }
11257     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
11258         TLOGE(WmsLogTag::WMS_FOCUS, "verify bundle failed, source name is %{public}s but target name is %{public}s)",
11259             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
11260         return WSError::WS_ERROR_INVALID_CALLING;
11261     }
11262     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
11263         return WSError::WS_ERROR_INVALID_CALLING;
11264     }
11265     int32_t callingPid = IPCSkeleton::GetCallingPid();
11266     if (callingPid != targetSession->GetCallingPid()) {
11267         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
11268         return WSError::WS_ERROR_INVALID_CALLING;
11269     }
11270     targetSession->NotifyClick(true, false);
11271     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
11272     return RequestSessionFocus(targetPersistentId, false, reason);
11273 }
11274 
GetAppMainSceneSession(int32_t persistentId,sptr<SceneSession> & sceneSession)11275 WSError SceneSessionManager::GetAppMainSceneSession(int32_t persistentId, sptr<SceneSession>& sceneSession)
11276 {
11277     sceneSession = GetSceneSession(persistentId);
11278     if (sceneSession == nullptr) {
11279         TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is nullptr", persistentId);
11280         return WSError::WS_ERROR_INVALID_SESSION;
11281     }
11282     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
11283         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
11284             TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is not main window or sub window", persistentId);
11285             return WSError::WS_ERROR_INVALID_CALLING;
11286         }
11287         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
11288         if (sceneSession == nullptr) {
11289             TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) parent is nullptr", persistentId);
11290             return WSError::WS_ERROR_INVALID_SESSION;
11291         }
11292     }
11293     return WSError::WS_OK;
11294 }
11295 
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)11296 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
11297     const float scaleParam)
11298 {
11299     auto sceneSession = GetSceneSession(persistentId);
11300     if (!sceneSession) {
11301         TLOGE(WmsLogTag::WMS_MAIN, "get scene session is nullptr");
11302         return nullptr;
11303     }
11304 
11305     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
11306 
11307     bool isPc = systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode();
11308     std::shared_ptr<Media::PixelMap> pixelMap = sceneSession->Snapshot(true, scaleParam, isPc);
11309     if (!pixelMap) {
11310         TLOGI(WmsLogTag::WMS_MAIN, "get local snapshot pixelmap start");
11311         pixelMap = sceneSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
11312     }
11313     return pixelMap;
11314 }
11315 
GetSceneSessionMap()11316 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
11317 {
11318     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
11319     {
11320         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11321         retSceneSessionMap = sceneSessionMap_;
11322     }
11323     EraseIf(retSceneSessionMap, [this](const auto& pair) {
11324         if (pair.second == nullptr) {
11325             return true;
11326         }
11327 
11328         if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
11329             if (pair.second->IsVisible()) {
11330                 return false;
11331             }
11332             return true;
11333         }
11334 
11335         if (pair.second->IsSystemInput()) {
11336             return false;
11337         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
11338             return false;
11339         }
11340 
11341         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
11342             return true;
11343         }
11344         return false;
11345     });
11346     return retSceneSessionMap;
11347 }
11348 
NotifyUpdateRectAfterLayout()11349 void SceneSessionManager::NotifyUpdateRectAfterLayout()
11350 {
11351     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
11352     if (auto transactionController = RSSyncTransactionController::GetInstance()) {
11353         rsTransaction = transactionController->GetRSTransaction();
11354     }
11355     auto task = [this, rsTransaction] {
11356         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11357         for (const auto& [_, sceneSession] : sceneSessionMap_) {
11358             if (sceneSession && sceneSession->IsDirtyWindow()) {
11359                 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
11360             }
11361         }
11362     };
11363     // need sync task since animation transcation need
11364     taskScheduler_->PostAsyncTask(task, __func__);
11365 }
11366 
ListWindowInfo(const WindowInfoOption & windowInfoOption,std::vector<sptr<WindowInfo>> & infos)11367 WMError SceneSessionManager::ListWindowInfo(const WindowInfoOption& windowInfoOption,
11368     std::vector<sptr<WindowInfo>>& infos)
11369 {
11370     if (!(SessionPermission::IsSACalling())) {
11371         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied");
11372         return WMError::WM_ERROR_INVALID_PERMISSION;
11373     }
11374     return taskScheduler_->PostSyncTask([this, windowInfoOption, &infos] {
11375         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11376         for (const auto& [_, sceneSession] : sceneSessionMap_) {
11377             if (sceneSession == nullptr) {
11378                 continue;
11379             }
11380             if (!FilterForListWindowInfo(windowInfoOption, sceneSession)) {
11381                 continue;
11382             }
11383             auto windowInfo = sptr<WindowInfo>::MakeSptr();
11384             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_UI_INFO)) {
11385                 windowInfo->windowUIInfo = sceneSession->GetWindowUIInfoForWindowInfo();
11386             }
11387             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_DISPLAY_INFO)) {
11388                 windowInfo->windowDisplayInfo = sceneSession->GetWindowDisplayInfoForWindowInfo();
11389             }
11390             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_LAYOUT_INFO)) {
11391                 windowInfo->windowLayoutInfo = sceneSession->GetWindowLayoutInfoForWindowInfo();
11392             }
11393             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_META_INFO)) {
11394                 windowInfo->windowMetaInfo = sceneSession->GetWindowMetaInfoForWindowInfo();
11395             }
11396             infos.emplace_back(windowInfo);
11397         }
11398         return WMError::WM_OK;
11399     }, __func__);
11400 }
11401 
FilterForListWindowInfo(const WindowInfoOption & windowInfoOption,const sptr<SceneSession> & sceneSession) const11402 bool SceneSessionManager::FilterForListWindowInfo(const WindowInfoOption& windowInfoOption,
11403     const sptr<SceneSession>& sceneSession) const
11404 {
11405     DisplayId displayId = windowInfoOption.displayId;
11406     if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(sceneSession->GetSessionProperty()->GetDisplayId())) {
11407         if (displayId == DEFAULT_DISPLAY_ID && sceneSession->GetSessionGlobalRect().posY_ >= GetFoldLowerScreenPosY()) {
11408             return false;
11409         }
11410         if (displayId == VIRTUAL_DISPLAY_ID) {
11411             if (sceneSession->GetSessionGlobalRect().posY_ +
11412                 sceneSession->GetSessionGlobalRect().height_ < GetFoldLowerScreenPosY()) {
11413                 return false;
11414             }
11415             displayId = DEFAULT_DISPLAY_ID;
11416         }
11417     }
11418     if (displayId != DISPLAY_ID_INVALID && sceneSession->GetSessionProperty()->GetDisplayId() != displayId) {
11419         return false;
11420     }
11421     if (windowInfoOption.windowId != 0 && sceneSession->GetWindowId() !=windowInfoOption.windowId) {
11422         return false;
11423     }
11424     if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::EXCLUDE_SYSTEM) &&
11425         sceneSession->GetSessionInfo().isSystem_) {
11426         return false;
11427     }
11428     if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::VISIBLE) &&
11429         (sceneSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION ||
11430         sceneSession->GetVisibilityState() == WINDOW_LAYER_STATE_MAX)) {
11431         return false;
11432     }
11433     if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::FOREGROUND) &&
11434         !IsSessionVisibleForeground(sceneSession)) {
11435         return false;
11436     }
11437     return true;
11438 }
11439 
GetAllWindowLayoutInfo(DisplayId displayId,std::vector<sptr<WindowLayoutInfo>> & infos)11440 WMError SceneSessionManager::GetAllWindowLayoutInfo(DisplayId displayId,
11441     std::vector<sptr<WindowLayoutInfo>>& infos)
11442 {
11443     auto task = [this, displayId, &infos]() mutable {
11444         bool isVirtualDisplay = false;
11445         if (displayId == VIRTUAL_DISPLAY_ID) {
11446             displayId = DEFAULT_DISPLAY_ID;
11447             isVirtualDisplay = true;
11448         }
11449         std::vector<sptr<SceneSession>> filteredSessions;
11450         FilterForGetAllWindowLayoutInfo(displayId, isVirtualDisplay, filteredSessions);
11451         for (const auto& session : filteredSessions) {
11452             Rect globalScaledRect;
11453             session->GetGlobalScaledRect(globalScaledRect);
11454             if (isVirtualDisplay) {
11455                 globalScaledRect.posY_ -= GetFoldLowerScreenPosY();
11456             }
11457             auto windowLayoutInfo = sptr<WindowLayoutInfo>::MakeSptr();
11458             windowLayoutInfo->rect = globalScaledRect;
11459             infos.emplace_back(windowLayoutInfo);
11460         }
11461         return WMError::WM_OK;
11462     };
11463     return taskScheduler_->PostSyncTask(task, __func__);
11464 }
11465 
FilterForGetAllWindowLayoutInfo(DisplayId displayId,bool isVirtualDisplay,std::vector<sptr<SceneSession>> & filteredSessions)11466 void SceneSessionManager::FilterForGetAllWindowLayoutInfo(DisplayId displayId, bool isVirtualDisplay,
11467     std::vector<sptr<SceneSession>>& filteredSessions)
11468 {
11469     {
11470         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11471         for (const auto& [_, session] : sceneSessionMap_) {
11472             if (session == nullptr) {
11473                 continue;
11474             }
11475             if (session->GetSessionGlobalRect().IsInvalid()) {
11476                 continue;
11477             }
11478             if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(session->GetSessionProperty()->GetDisplayId()) &&
11479                 displayId == DEFAULT_DISPLAY_ID) {
11480                 if (isVirtualDisplay &&
11481                     session->GetSessionRect().posY_ + session->GetSessionRect().height_ < GetFoldLowerScreenPosY()) {
11482                     continue;
11483                 }
11484                 if (!isVirtualDisplay && session->GetSessionRect().posY_ >= GetFoldLowerScreenPosY()) {
11485                     continue;
11486                 }
11487             }
11488             if (IsGetWindowLayoutInfoNeeded(session) && session->GetSessionProperty()->GetDisplayId() == displayId &&
11489                 session->GetVisibilityState() != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11490                 filteredSessions.emplace_back(session);
11491             }
11492         }
11493     }
11494     std::sort(filteredSessions.begin(), filteredSessions.end(),
11495               [](const sptr<SceneSession>& lhs, const sptr<SceneSession>& rhs) {
11496                   return lhs->GetZOrder() > rhs->GetZOrder();
11497               });
11498 }
11499 
GetFoldLowerScreenPosY() const11500 int32_t SceneSessionManager::GetFoldLowerScreenPosY() const
11501 {
11502     const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
11503         PcFoldScreenManager::GetInstance().GetDisplayRects();
11504     constexpr int32_t SUPER_FOLD_DIVIDE_FACTOR = 2;
11505     return foldCreaseRect.height_ != 0 ?
11506            defaultDisplayRect.height_ - foldCreaseRect.height_ / SUPER_FOLD_DIVIDE_FACTOR + foldCreaseRect.height_ :
11507            defaultDisplayRect.height_;
11508 }
11509 
IsGetWindowLayoutInfoNeeded(const sptr<SceneSession> & session) const11510 bool SceneSessionManager::IsGetWindowLayoutInfoNeeded(const sptr<SceneSession>& session) const
11511 {
11512     constexpr int32_t GROUP_ONE = 1;
11513     std::string name = session->GetWindowName();
11514     std::regex pattern("^(.*?)(\\d*)$"); // Remove last digit
11515     std::smatch matches;
11516     name = std::regex_search(name, matches, pattern) ? matches[GROUP_ONE] : name;
11517     return !session->GetSessionInfo().isSystem_ || LAYOUT_INFO_WHITELIST.find(name) != LAYOUT_INFO_WHITELIST.end();
11518 }
11519 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)11520 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
11521 {
11522     if (!SessionPermission::IsSystemCalling() &&
11523         !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_VISIBLE_WINDOW_INFO)) {
11524         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
11525         return WMError::WM_ERROR_INVALID_PERMISSION;
11526     }
11527     auto task = [this, &infos]() {
11528         for (auto [surfaceId, _] : lastVisibleData_) {
11529             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11530             if (session == nullptr) {
11531                 continue;
11532             }
11533             WSRect hostRect = session->GetSessionRect();
11534             Rect rect = {hostRect.posX_, hostRect.posY_,
11535                          static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
11536             auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
11537                                                 session->GetSessionProperty());
11538             auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
11539                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
11540                 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
11541                 session->IsFocused());
11542             windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
11543             windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
11544             infos.emplace_back(windowVisibilityInfo);
11545         }
11546         return WMError::WM_OK;
11547     };
11548     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
11549 }
11550 
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)11551 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
11552 {
11553     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11554     for (const auto& [id, session] : sceneSessionMap_) {
11555         if (session == nullptr) {
11556             continue;
11557         }
11558         uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
11559         windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
11560     }
11561 }
11562 
FlushWindowInfoToMMI(const bool forceFlush)11563 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
11564 {
11565     auto task = [this, forceFlush] {
11566         if (isUserBackground_) {
11567             TLOGND(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
11568             return;
11569         }
11570         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
11571         SceneInputManager::GetInstance().ResetSessionDirty();
11572         auto [windowInfoList, pixelMapList] = SceneInputManager::GetInstance().GetFullWindowInfoList();
11573         TLOGND(WmsLogTag::WMS_EVENT, "windowInfoList size: %{public}d", static_cast<int32_t>(windowInfoList.size()));
11574         if (windowInfoList.empty()) {
11575             std::ostringstream oss;
11576             oss << "windowInfoList flush to MMI is empty!";
11577             int32_t ret = WindowInfoReporter::GetInstance().ReportEventDispatchException(
11578                 static_cast<int32_t>(WindowDFXHelperType::WINDOW_FLUSH_EMPTY_WINDOW_INFO_TO_MMI_EXCEPTION),
11579                 getpid(), oss.str()
11580             );
11581             if (ret != 0) {
11582                 TLOGNI(WmsLogTag::WMS_EVENT, "ReportEventDispatchException message failed, ret: %{public}d", ret);
11583             }
11584         }
11585         SceneInputManager::GetInstance().
11586             FlushDisplayInfoToMMI(std::move(windowInfoList), std::move(pixelMapList), forceFlush);
11587     };
11588     TLOGD(WmsLogTag::WMS_EVENT, "in");
11589     taskScheduler_->PostAsyncTask(task, __func__);
11590 }
11591 
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string & taskName,const int delayTime)11592 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask&& task,
11593     const std::string& taskName, const int delayTime)
11594 {
11595     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
11596 }
11597 
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)11598 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
11599     int32_t& parentId)
11600 {
11601     // This function should be called in task
11602     auto iter = extSessionInfoMap_.find(token);
11603     if (iter == extSessionInfoMap_.end()) {
11604         return false;
11605     }
11606     persistentId = iter->second.persistentId;
11607     parentId = iter->second.parentId;
11608     return true;
11609 }
11610 
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession,bool isConstrainedModal)11611 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession, bool isConstrainedModal)
11612 {
11613     const char* const where = __func__;
11614     auto task = [this, remoteExtSession, isConstrainedModal, where]() {
11615         auto iter = remoteExtSessionMap_.find(remoteExtSession);
11616         if (iter == remoteExtSessionMap_.end()) {
11617             TLOGNI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
11618             return;
11619         }
11620         int32_t persistentId = INVALID_SESSION_ID;
11621         int32_t parentId = INVALID_SESSION_ID;
11622         auto abilityToken = iter->second;
11623         if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
11624             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11625             return;
11626         }
11627 
11628         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d",
11629             where, persistentId, parentId);
11630         auto sceneSession = GetSceneSession(parentId);
11631         if (sceneSession != nullptr) {
11632             auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
11633             sceneSession->RemoveExtWindowFlags(persistentId);
11634             if (oldFlags.hideNonSecureWindowsFlag) {
11635                 HandleSecureSessionShouldHide(sceneSession);
11636             }
11637             if (oldFlags.waterMarkFlag) {
11638                 CheckAndNotifyWaterMarkChangedResult();
11639             }
11640             if (oldFlags.privacyModeFlag) {
11641                 UpdatePrivateStateAndNotify(parentId);
11642             }
11643             if (!isConstrainedModal) {
11644                 sceneSession->RemoveNormalModalUIExtension(persistentId);
11645             }
11646             sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
11647             sceneSession->RemoveExtensionTokenInfo(abilityToken);
11648         } else {
11649             ExtensionWindowFlags actions;
11650             actions.SetAllActive();
11651             HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
11652         }
11653         extSessionInfoMap_.erase(iter->second);
11654         remoteExtSessionMap_.erase(iter);
11655     };
11656     taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
11657 }
11658 
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)11659 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
11660 {
11661     auto pid = IPCSkeleton::GetCallingRealPid();
11662     const char* const where = __func__;
11663     auto task = [this, token, pid, rect, where]() {
11664         int32_t persistentId = INVALID_SESSION_ID;
11665         int32_t parentId = INVALID_SESSION_ID;
11666         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
11667             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11668             return;
11669         }
11670         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
11671             "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
11672             where, pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
11673         auto parentSession = GetSceneSession(parentId);
11674         if (parentSession) {
11675             auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetClientRect().posX_;
11676             auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetClientRect().posY_;
11677             Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
11678             ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
11679             TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid: %{public}d, persistentId: %{public}d, "
11680                 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
11681                 where, pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
11682                 parentSession->GetSessionGlobalRect().ToString().c_str());
11683             parentSession->UpdateNormalModalUIExtension(extensionInfo);
11684         }
11685     };
11686     taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
11687 }
11688 
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)11689 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
11690 {
11691     auto pid = IPCSkeleton::GetCallingRealPid();
11692     const char* const where = __func__;
11693     auto task = [this, token, pid, posX, posY, where]() {
11694         int32_t persistentId = INVALID_SESSION_ID;
11695         int32_t parentId = INVALID_SESSION_ID;
11696         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
11697             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11698             return;
11699         }
11700         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
11701             "parentId=%{public}d", where, pid, persistentId, parentId);
11702         auto parentSession = GetSceneSession(parentId);
11703         if (parentSession) {
11704             auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
11705             if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
11706                 modalUIExtensionEventInfo.value().persistentId == persistentId) {
11707                 parentSession->ProcessPointDownSession(posX, posY);
11708             }
11709         }
11710     };
11711     taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
11712 }
11713 
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId,bool isConstrainedModal)11714 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
11715     const sptr<IRemoteObject>& token, uint64_t surfaceNodeId, bool isConstrainedModal)
11716 {
11717     auto pid = IPCSkeleton::GetCallingRealPid();
11718     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
11719     const char* const where = __func__;
11720     auto task = [this, sessionStage, token, surfaceNodeId, isConstrainedModal, pid, callingTokenId, where]() {
11721         if (sessionStage == nullptr || token == nullptr) {
11722             TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
11723             return;
11724         }
11725         auto remoteExtSession = sessionStage->AsObject();
11726         if (remoteExtSession == nullptr) {
11727             TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
11728             return;
11729         }
11730         if (extensionDeath_ == nullptr) {
11731             TLOGNE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
11732             return;
11733         }
11734         if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
11735             TLOGNE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
11736             return;
11737         }
11738 
11739         AAFwk::UIExtensionSessionInfo info;
11740         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
11741         if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
11742             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
11743             return;
11744         }
11745 
11746         int32_t persistentId = info.persistentId;
11747         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
11748         UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
11749         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d, "
11750             "usage=%{public}u, surfaceNodeId=%{public}" PRIu64 ", pid=%{public}d",
11751             where, persistentId, parentId, usage, surfaceNodeId, pid);
11752 
11753         remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
11754         extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
11755 
11756         auto parentSession = GetSceneSession(parentId);
11757         if (!parentSession) {
11758             TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
11759             return;
11760         }
11761 
11762         UIExtensionTokenInfo tokenInfo;
11763         tokenInfo.abilityToken = token;
11764         tokenInfo.callingTokenId = callingTokenId;
11765         tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
11766             info.extensionAbilityType);
11767         parentSession->AddExtensionTokenInfo(tokenInfo);
11768         parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
11769         if (usage == UIExtensionUsage::MODAL && parentSession->GetCallingPid() != GetPid()) {
11770             ExtensionWindowEventInfo extensionInfo {
11771                 .persistentId = persistentId,
11772                 .pid = pid,
11773             };
11774             if (!isConstrainedModal) {
11775                 parentSession->AddNormalModalUIExtension(extensionInfo);
11776             }
11777         }
11778     };
11779     taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
11780 }
11781 
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,bool isConstrainedModal)11782 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
11783     const sptr<IRemoteObject>& token, bool isConstrainedModal)
11784 {
11785     TLOGI(WmsLogTag::WMS_UIEXT, "in");
11786     auto task = [this, sessionStage, token, isConstrainedModal]() {
11787         if (sessionStage == nullptr || token == nullptr) {
11788             TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
11789             return;
11790         }
11791         auto remoteExtSession = sessionStage->AsObject();
11792         if (remoteExtSession == nullptr) {
11793             TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
11794             return;
11795         }
11796         auto iter = remoteExtSessionMap_.find(remoteExtSession);
11797         if (iter == remoteExtSessionMap_.end() || iter->second != token) {
11798             TLOGNE(WmsLogTag::WMS_UIEXT, "token not match");
11799             return;
11800         }
11801 
11802         DestroyExtensionSession(remoteExtSession, isConstrainedModal);
11803     };
11804     taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
11805 }
11806 
CalculateCombinedExtWindowFlags()11807 void SceneSessionManager::CalculateCombinedExtWindowFlags()
11808 {
11809     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
11810     combinedExtWindowFlags_.bitData = 0;
11811     for (const auto& iter: extWindowFlagsMap_) {
11812         combinedExtWindowFlags_.bitData |= iter.second.bitData;
11813     }
11814     specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
11815 }
11816 
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)11817 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
11818     ExtensionWindowFlags actions)
11819 {
11820     auto iter = extWindowFlagsMap_.find(persistentId);
11821     // Each flag is false when inactive, 0 means all flags are inactive
11822     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
11823     ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
11824     if (newFlags.bitData == 0) {
11825         extWindowFlagsMap_.erase(persistentId);
11826     } else {
11827         extWindowFlagsMap_[persistentId] = newFlags;
11828     }
11829     CalculateCombinedExtWindowFlags();
11830 }
11831 
HideNonSecureFloatingWindows()11832 void SceneSessionManager::HideNonSecureFloatingWindows()
11833 {
11834     if (systemConfig_.IsPcWindow()) {
11835         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
11836         return;
11837     }
11838     bool shouldHide = false;
11839     {
11840         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11841         for (const auto& iter: sceneSessionMap_) {
11842             auto& session = iter.second;
11843             if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
11844                 shouldHide = true;
11845                 break;
11846             }
11847         }
11848     }
11849     if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
11850         TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
11851         shouldHide = true;
11852     }
11853     if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
11854         return;
11855     }
11856 
11857     shouldHideNonSecureFloatingWindows_.store(shouldHide);
11858     for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
11859         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
11860             session->NotifyForceHideChange(shouldHide);
11861             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
11862                 session->GetWindowName().c_str(), persistentId, shouldHide);
11863         }
11864     }
11865 }
11866 
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)11867 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
11868 {
11869     // don't let sub-window show when switching secure host window to background
11870     if (!sceneSession->IsSessionForeground()) {
11871         return;
11872     }
11873 
11874     auto parentId = sceneSession->GetPersistentId();
11875     bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
11876     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11877     for (const auto& [_, session] : sceneSessionMap_) {
11878         if (!session) {
11879             continue;
11880         }
11881         auto sessionProperty = session->GetSessionProperty();
11882         if (sessionProperty->GetParentPersistentId() != parentId) {
11883             continue;
11884         }
11885         if (SessionHelper::IsNonSecureToUIExtension(sessionProperty->GetWindowType()) &&
11886             !session->IsSystemSpecificSession()) {
11887             session->NotifyForceHideChange(shouldHide);
11888             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
11889                 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
11890         }
11891     }
11892 }
11893 
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)11894 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
11895 {
11896     if (sceneSession == nullptr) {
11897         TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
11898         return WSError::WS_ERROR_INVALID_SESSION;
11899     }
11900 
11901     HideNonSecureFloatingWindows();
11902     HideNonSecureSubWindows(sceneSession);
11903     return WSError::WS_OK;
11904 }
11905 
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)11906 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
11907     ExtensionWindowFlags actions)
11908 {
11909     UpdateSpecialExtWindowFlags(persistentId, flags, actions);
11910     if (actions.waterMarkFlag) {
11911         CheckAndNotifyWaterMarkChangedResult();
11912     }
11913     if (actions.hideNonSecureWindowsFlag) {
11914         HideNonSecureFloatingWindows();
11915     }
11916     if (actions.privacyModeFlag) {
11917         UpdatePrivateStateAndNotifyForAllScreens();
11918     }
11919 }
11920 
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)11921 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
11922 {
11923     TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
11924     if (!SessionPermission::IsSystemCalling()) {
11925         TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
11926         return WSError::WS_ERROR_NOT_SYSTEM_APP;
11927     }
11928     const auto callingPid = IPCSkeleton::GetCallingRealPid();
11929     const char* const where = __func__;
11930     auto task = [this, persistentId, shouldHide, callingPid, where]() {
11931         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11932         auto iter = sceneSessionMap_.find(persistentId);
11933         if (iter == sceneSessionMap_.end()) {
11934             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Session with persistentId %{public}d not found",
11935                 where, persistentId);
11936             return WSError::WS_ERROR_INVALID_SESSION;
11937         }
11938         auto sceneSession = iter->second;
11939         if (sceneSession == nullptr) {
11940             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: sceneSession is nullptr.", where);
11941             return WSError::WS_ERROR_NULLPTR;
11942         }
11943         if (callingPid != sceneSession->GetCallingPid()) {
11944             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Permission denied", where);
11945             return WSError::WS_ERROR_INVALID_PERMISSION;
11946         }
11947         sceneSession->SetShouldHideNonSecureWindows(shouldHide);
11948         return HandleSecureSessionShouldHide(sceneSession);
11949     };
11950 
11951     taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
11952     return WSError::WS_OK;
11953 }
11954 
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const11955 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
11956 {
11957     auto ret = WSError::WS_OK;
11958     bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
11959     if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
11960         actions.hideNonSecureWindowsFlag = false;
11961         actions.waterMarkFlag = false;
11962         TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
11963         ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
11964     }
11965     auto needPrivacyWindow = actions.privacyModeFlag;
11966     if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
11967         actions.privacyModeFlag = false;
11968         TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
11969         ret = WSError::WS_ERROR_INVALID_PERMISSION;
11970     }
11971     return ret;
11972 }
11973 
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)11974 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
11975     uint32_t extWindowActions)
11976 {
11977     ExtensionWindowFlags actions(extWindowActions);
11978     auto ret = CheckExtWindowFlagsPermission(actions);
11979     if (actions.bitData == 0) {
11980         return ret;
11981     }
11982 
11983     ExtensionWindowFlags flags(extWindowFlags);
11984     const char* const where = __func__;
11985     auto task = [this, token, flags, actions, where]() {
11986         int32_t persistentId = INVALID_SESSION_ID;
11987         int32_t parentId = INVALID_SESSION_ID;
11988         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
11989             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11990             return WSError::WS_ERROR_INVALID_OPERATION;
11991         }
11992 
11993         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: parentId=%{public}d, persistentId=%{public}d, "
11994             "extWindowFlags=%{public}d, actions=%{public}d", where, parentId, persistentId,
11995             flags.bitData, actions.bitData);
11996         auto sceneSession = GetSceneSession(parentId);
11997         if (sceneSession == nullptr) {
11998             TLOGND(WmsLogTag::WMS_UIEXT, "%{public}s: Parent session with persistentId %{public}d not found",
11999                 where, parentId);
12000             HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
12001             return WSError::WS_OK;
12002         }
12003 
12004         auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
12005         sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
12006         auto newFlags = sceneSession->GetCombinedExtWindowFlags();
12007         if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
12008             HandleSecureSessionShouldHide(sceneSession);
12009         }
12010         if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
12011             CheckAndNotifyWaterMarkChangedResult();
12012         }
12013         if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
12014             UpdatePrivateStateAndNotify(parentId);
12015         }
12016         return WSError::WS_OK;
12017     };
12018 
12019     taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
12020     return ret;
12021 }
12022 
GetHostWindowRect(int32_t hostWindowId,Rect & rect)12023 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
12024 {
12025     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
12026     if (!SessionPermission::IsSystemCalling()) {
12027         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
12028         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12029     }
12030     auto task = [this, hostWindowId, &rect]() {
12031         auto sceneSession = GetSceneSession(hostWindowId);
12032         if (sceneSession == nullptr) {
12033             TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
12034             return WSError::WS_ERROR_INVALID_SESSION;
12035         }
12036         WSRect hostRect = sceneSession->GetSessionRect();
12037         auto currScreenFoldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
12038         auto needTransRect = currScreenFoldStatus != SuperFoldStatus::UNKNOWN &&
12039             currScreenFoldStatus != SuperFoldStatus::FOLDED && currScreenFoldStatus != SuperFoldStatus::EXPANDED;
12040         auto isSystemKeyboard = sceneSession->GetSessionProperty() != nullptr &&
12041             sceneSession->GetSessionProperty()->IsSystemKeyboard();
12042         if (!isSystemKeyboard && needTransRect) {
12043             WSRect globalRect = hostRect;
12044             sceneSession->TransformGlobalRectToRelativeRect(hostRect);
12045             TLOGI(WmsLogTag::WMS_UIEXT, "Transform globalRect: %{public}s to relativeRect: %{public}s",
12046                 globalRect.ToString().c_str(), hostRect.ToString().c_str());
12047         }
12048         rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
12049         return WSError::WS_OK;
12050     };
12051     taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
12052     return WSError::WS_OK;
12053 }
12054 
ReclaimPurgeableCleanMem()12055 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
12056 {
12057 #ifdef MEMMGR_WINDOW_ENABLE
12058     return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
12059 #else
12060     return -1;
12061 #endif
12062 }
12063 
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)12064 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
12065     const std::vector<VisibleWindowNumInfo>& currentInfo)
12066 {
12067     if (lastInfo.size() != currentInfo.size()) {
12068         TLOGE(WmsLogTag::DEFAULT, "last and current info is not Same");
12069         return false;
12070     }
12071     int sizeOfLastInfo = static_cast<int>(lastInfo.size());
12072     for (int i = 0; i < sizeOfLastInfo; i++) {
12073         if (lastInfo[i].displayId != currentInfo[i].displayId ||
12074             lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
12075             TLOGE(WmsLogTag::DEFAULT, "last and current visible window num is not Same");
12076             return false;
12077         }
12078     }
12079     return true;
12080 }
12081 
CacVisibleWindowNum()12082 void SceneSessionManager::CacVisibleWindowNum()
12083 {
12084     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
12085     {
12086         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12087         sceneSessionMapCopy = sceneSessionMap_;
12088     }
12089     std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
12090     bool isFullScreen = true;
12091     for (const auto& elem : sceneSessionMapCopy) {
12092         auto curSession = elem.second;
12093         if (curSession == nullptr) {
12094             continue;
12095         }
12096         bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
12097             curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
12098         if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
12099             continue;
12100         }
12101 
12102         bool isWindowVisible = curSession->GetRSVisible();
12103         if (isWindowVisible) {
12104             auto windowMode = curSession->GetWindowMode();
12105             if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
12106                 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
12107                 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
12108                 isFullScreen = false;
12109             }
12110             int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
12111             auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
12112                 [displayId](const VisibleWindowNumInfo& info) {
12113                     return (static_cast<int32_t>(info.displayId)) == displayId;
12114                 });
12115             if (it == visibleWindowNumInfo.end()) {
12116                 visibleWindowNumInfo.push_back({displayId, 1});
12117             } else {
12118                 it->visibleWindowNum++;
12119             }
12120         }
12121     }
12122     if (isFullScreen) {
12123         std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
12124                       [](auto& info) { info.visibleWindowNum = 1; });
12125     }
12126     std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
12127     if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
12128         SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
12129         lastInfo_ = visibleWindowNumInfo;
12130     }
12131 }
12132 
ReportWindowProfileInfos()12133 void SceneSessionManager::ReportWindowProfileInfos()
12134 {
12135     enum class WindowVisibleState : int32_t {
12136         FOCUSBLE = 0,
12137         VISIBLE,
12138         MINIMIZED,
12139         OCCLUSION
12140     };
12141     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
12142     {
12143         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12144         sceneSessionMapCopy = sceneSessionMap_;
12145     }
12146     auto focusWindowId = GetFocusedSessionId();
12147     for (const auto& [_, currSession] : sceneSessionMapCopy) {
12148         if (currSession == nullptr || currSession->GetSessionInfo().isSystem_ ||
12149             currSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
12150             continue;
12151         }
12152         WindowProfileInfo windowProfileInfo;
12153         windowProfileInfo.bundleName = currSession->GetSessionInfo().bundleName_;
12154         windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
12155             currSession->GetSessionProperty()->GetDisplayId());
12156         windowProfileInfo.windowSceneMode = static_cast<int32_t>(currSession->GetWindowMode());
12157         if (focusWindowId == static_cast<int32_t>(currSession->GetWindowId())) {
12158             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
12159         } else if (currSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
12160             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
12161         } else if (!currSession->GetRSVisible()) {
12162             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
12163         } else {
12164             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
12165         }
12166         WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
12167         TLOGD(WmsLogTag::DEFAULT, "bundleName:%{public}s, windowVisibleState:%{public}d, "
12168             "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
12169             windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
12170             windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
12171     }
12172 }
12173 
GetCustomDecorHeight(int32_t persistentId)12174 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
12175 {
12176     int32_t height = 0;
12177     auto sceneSession = GetSceneSession(persistentId);
12178     if (sceneSession == nullptr) {
12179         TLOGE(WmsLogTag::WMS_DECOR, "session is invalid, id: %{public}d", persistentId);
12180         return 0;
12181     }
12182     height = sceneSession->GetCustomDecorHeight();
12183     TLOGD(WmsLogTag::WMS_DECOR, "decor height: %{public}d", height);
12184     return height;
12185 }
12186 
RemoveFailRecoveredSession()12187 void SceneSessionManager::RemoveFailRecoveredSession()
12188 {
12189     for (const auto persistentId : failRecoveredPersistentIdSet_) {
12190         auto sceneSession = GetSceneSession(persistentId);
12191         if (sceneSession == nullptr) {
12192             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
12193             continue;
12194         }
12195         if (!sceneSession->IsRecovered()) {
12196             TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId=%{public}d", persistentId);
12197             continue;
12198         }
12199         TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId=%{public}d", persistentId);
12200         ExceptionInfo exceptionInfo;
12201         exceptionInfo.needRemoveSession = true;
12202         sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
12203     }
12204     failRecoveredPersistentIdSet_.clear();
12205 }
12206 
GetDisplayRegion(DisplayId displayId)12207 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
12208 {
12209     if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
12210         return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
12211     }
12212     TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
12213     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
12214     if (display == nullptr) {
12215         TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
12216         return nullptr;
12217     }
12218     auto displayInfo = display->GetDisplayInfo();
12219     if (displayInfo == nullptr) {
12220         TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
12221         return nullptr;
12222     }
12223     int32_t displayWidth = displayInfo->GetWidth();
12224     int32_t displayHeight = displayInfo->GetHeight();
12225     if (displayWidth == 0 || displayHeight == 0) {
12226         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
12227         return nullptr;
12228     }
12229     if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
12230         const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
12231             PcFoldScreenManager::GetInstance().GetDisplayRects();
12232         displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
12233         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
12234     }
12235     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
12236     auto region = std::make_shared<SkRegion>(rect);
12237     displayRegionMap_[displayId] = region;
12238     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w=%{public}d, h=%{public}d", displayWidth, displayHeight);
12239     return std::make_shared<SkRegion>(rect);
12240 }
12241 
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)12242 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
12243 {
12244     if (displayInfo == nullptr) {
12245         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "update display region failed, displayInfo is nullptr.");
12246         return;
12247     }
12248     auto displayId = displayInfo->GetDisplayId();
12249     int32_t displayWidth = displayInfo->GetWidth();
12250     int32_t displayHeight = displayInfo->GetHeight();
12251     if (displayWidth == 0 || displayHeight == 0) {
12252         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid display size of display: %{public}" PRIu64, displayId);
12253         return;
12254     }
12255     if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
12256         const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
12257             PcFoldScreenManager::GetInstance().GetDisplayRects();
12258         displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
12259         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
12260     }
12261     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
12262     auto region = std::make_shared<SkRegion>(rect);
12263     displayRegionMap_[displayId] = region;
12264     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "update display region to w: %{public}d, h: %{public}d",
12265         displayWidth, displayHeight);
12266 }
12267 
GetDisplaySizeById(DisplayId displayId,int32_t & displayWidth,int32_t & displayHeight)12268 bool SceneSessionManager::GetDisplaySizeById(DisplayId displayId, int32_t& displayWidth, int32_t& displayHeight)
12269 {
12270     auto region = GetDisplayRegion(displayId);
12271     if (region == nullptr) {
12272         TLOGW(WmsLogTag::WMS_LAYOUT, "failed, displayId:%{public}" PRIu64, displayId);
12273         return false;
12274     }
12275     const SkIRect& rect = region->getBounds();
12276     displayWidth = rect.fRight;
12277     displayHeight = rect.fBottom;
12278     return true;
12279 }
12280 
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)12281 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
12282 {
12283     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12284     for (const auto& [_, sceneSession] : sceneSessionMap_) {
12285         if (sceneSession == nullptr) {
12286             continue;
12287         }
12288         if (Session::IsScbCoreEnabled()) {
12289             if (!sceneSession->IsVisibleForAccessibility()) {
12290                 continue;
12291             }
12292         } else {
12293             if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
12294                 continue;
12295             }
12296         }
12297         if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
12298             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
12299             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
12300             continue;
12301         }
12302         if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
12303             continue;
12304         }
12305         sceneSessionList.push_back(sceneSession);
12306     }
12307 }
12308 
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)12309 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
12310     std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
12311 {
12312     for (const auto& sceneSession : sceneSessionList) {
12313         if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
12314             TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
12315         }
12316     }
12317 }
12318 
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)12319 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
12320 {
12321     std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
12322         return a->GetZOrder() > b->GetZOrder();
12323     });
12324     std::vector<sptr<SceneSession>> result;
12325     std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
12326     for (const auto& sceneSession : sceneSessionList) {
12327         if (sceneSession == nullptr) {
12328             TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
12329             continue;
12330         }
12331         std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
12332         auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
12333         if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
12334             unaccountedSpace = unaccountedSpaceMap[displayId];
12335         } else {
12336             unaccountedSpace = GetDisplayRegion(displayId);
12337             if (unaccountedSpace == nullptr) {
12338                 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
12339                 continue;
12340             }
12341             unaccountedSpaceMap[displayId] = unaccountedSpace;
12342         }
12343         WSRect wsRect = sceneSession->GetSessionRect();
12344         SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
12345                               .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
12346         SkRegion windowRegion(windowBounds);
12347         if (unaccountedSpace->quickReject(windowRegion)) {
12348             TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
12349                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
12350             continue;
12351         }
12352         if (!unaccountedSpace->intersects(windowRegion)) {
12353             TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
12354                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
12355             continue;
12356         }
12357         result.push_back(sceneSession);
12358         unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
12359         if (unaccountedSpace->isEmpty()) {
12360             break;
12361         }
12362     }
12363     sceneSessionList = result;
12364 }
12365 
NotifyAllAccessibilityInfo()12366 void SceneSessionManager::NotifyAllAccessibilityInfo()
12367 {
12368     if (isUserBackground_) {
12369         TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
12370         return;
12371     }
12372     std::vector<sptr<SceneSession>> sceneSessionList;
12373     GetAllSceneSessionForAccessibility(sceneSessionList);
12374     FilterSceneSessionCovered(sceneSessionList);
12375 
12376     std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
12377     FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
12378 
12379     for (const auto& item : accessibilityInfo) {
12380         TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid=%{public}d, inWid=%{public}d, "
12381             "bundle=%{public}s,bounds=(x=%{public}d, y=%{public}d, w=%{public}d, h=%{public}d)",
12382             item->wid_, item->innerWid_, item->bundleName_.c_str(),
12383             item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
12384         for (const auto& rect : item->touchHotAreas_) {
12385             TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d,"
12386                 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
12387         }
12388     }
12389 
12390     SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
12391         WindowUpdateType::WINDOW_UPDATE_ALL);
12392 }
12393 
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)12394 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
12395     const sptr<WindowSessionProperty>& property)
12396 {
12397     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
12398     if (property == nullptr) {
12399         return windowStatus;
12400     }
12401     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
12402         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
12403         if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
12404             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
12405         }
12406     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
12407         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
12408     } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
12409         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
12410     } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
12411         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
12412     }
12413     return windowStatus;
12414 }
12415 
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)12416 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
12417 {
12418     if (!SessionPermission::IsStartedByInputMethod()) {
12419         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
12420         return WMError::WM_ERROR_INVALID_PERMISSION;
12421     }
12422     auto sceneSession = GetSceneSession(persistentId);
12423     if (sceneSession == nullptr) {
12424         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
12425         return WMError::WM_ERROR_NULLPTR;
12426     }
12427     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
12428     auto focusedSessionId = GetFocusedSessionId(displayId);
12429     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
12430         persistentId, sceneSession->GetWindowType());
12431     uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
12432     auto callingSession = GetSceneSession(callingWindowId);
12433     if (callingSession == nullptr) {
12434         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
12435         callingSession = GetSceneSession(focusedSessionId);
12436         if (callingSession == nullptr) {
12437             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
12438             return WMError::WM_ERROR_INVALID_WINDOW;
12439         }
12440     }
12441     if (callingSession->IsSystemSession()) {
12442         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
12443     } else {
12444         windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
12445             callingSession->GetSessionProperty());
12446     }
12447     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
12448         persistentId, windowStatus);
12449     return WMError::WM_OK;
12450 }
12451 
GetCallingWindowRect(int32_t persistentId,Rect & rect)12452 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
12453 {
12454     if (!SessionPermission::IsStartedByInputMethod()) {
12455         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
12456         return WMError::WM_ERROR_INVALID_PERMISSION;
12457     }
12458     auto sceneSession = GetSceneSession(persistentId);
12459     if (sceneSession == nullptr) {
12460         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
12461         return WMError::WM_ERROR_NULLPTR;
12462     }
12463     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
12464     auto focusedSessionId = GetFocusedSessionId(displayId);
12465     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
12466         persistentId, sceneSession->GetWindowType());
12467     uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
12468     auto callingSession = GetSceneSession(callingWindowId);
12469     if (callingSession == nullptr) {
12470         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
12471         callingSession = GetSceneSession(focusedSessionId);
12472         if (callingSession == nullptr) {
12473             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
12474             return WMError::WM_ERROR_INVALID_WINDOW;
12475         }
12476     }
12477     WSRect sessionRect = callingSession->GetSessionRect();
12478     rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
12479     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
12480         "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
12481     return WMError::WM_OK;
12482 }
12483 
GetWindowModeType(WindowModeType & windowModeType)12484 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
12485 {
12486     if (!SessionPermission::IsSACalling()) {
12487         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
12488         return WMError::WM_ERROR_INVALID_PERMISSION;
12489     }
12490     windowModeType = CheckWindowModeType();
12491     return WMError::WM_OK;
12492 }
12493 
GetWindowStyleType(WindowStyleType & windowStyleType)12494 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
12495 {
12496     if (!SessionPermission::IsSACalling()) {
12497         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
12498         return WMError::WM_ERROR_INVALID_PERMISSION;
12499     }
12500     if (systemConfig_.IsPcWindow()) {
12501         windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
12502         return WMError::WM_OK;
12503     }
12504     windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
12505         WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
12506     return WMError::WM_OK;
12507 }
12508 
CheckSceneZOrder()12509 void SceneSessionManager::CheckSceneZOrder()
12510 {
12511     auto task = [this]() {
12512         AnomalyDetection::SceneZOrderCheckProcess();
12513     };
12514     taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
12515 }
12516 
NotifyEnterRecentTask(bool enterRecent)12517 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
12518 {
12519     TLOGI(WmsLogTag::WMS_IMMS, "enterRecent %{public}u", enterRecent);
12520     enterRecent_.store(enterRecent);
12521     SetSystemAnimatedScenes(enterRecent ?
12522         SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
12523     auto task = [this] {
12524         for (auto persistentId : gestureBackEnableWindowIdSet_) {
12525             auto sceneSession = GetSceneSession(persistentId);
12526             if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
12527                 continue;
12528             }
12529             UpdateGestureBackEnabled(persistentId);
12530         }
12531     };
12532     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
12533     return WSError::WS_OK;
12534 }
12535 
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)12536 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
12537 {
12538     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
12539         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
12540         return WMError::WM_ERROR_INVALID_PERMISSION;
12541     }
12542 
12543     if (!topNInfo.empty() || (topNum <= 0)) {
12544         return WMError::WM_ERROR_INVALID_PARAM;
12545     }
12546 
12547     TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
12548     auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
12549         if (session == nullptr) {
12550             return false;
12551         }
12552 
12553         if (topNum == 0) {
12554             return true;
12555         }
12556 
12557         if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
12558             TLOGND(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
12559             return false;
12560         }
12561 
12562         MainWindowInfo info;
12563         info.pid_ = session->GetCallingPid();
12564         info.bundleName_ = session->GetSessionInfo().bundleName_;
12565         topNInfo.push_back(info);
12566         topNum--;
12567         TLOGNE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
12568             topNum, info.pid_, info.bundleName_.c_str());
12569         return false;
12570     };
12571     TraverseSessionTree(func, true);
12572 
12573     return WMError::WM_OK;
12574 }
12575 
GetCallingWindowInfo(CallingWindowInfo & callingWindowInfo)12576 WMError SceneSessionManager::GetCallingWindowInfo(CallingWindowInfo& callingWindowInfo)
12577 {
12578     int32_t curUserId = GetUserIdByUid(getuid());
12579     if (curUserId != callingWindowInfo.userId_) {
12580         TLOGE(WmsLogTag::WMS_KEYBOARD, "Target user not exists, targetUserId: %{public}d, curUserId: %{public}d, id: %{public}d",
12581             callingWindowInfo.userId_, curUserId, callingWindowInfo.windowId_);
12582         return WMError::WM_ERROR_INVALID_PARAM;
12583     }
12584     auto sceneSession = GetSceneSession(callingWindowInfo.windowId_);
12585     if (sceneSession == nullptr) {
12586         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is nullptr, id: %{public}d", callingWindowInfo.windowId_);
12587         return WMError::WM_ERROR_NULLPTR;
12588     }
12589     callingWindowInfo.callingPid_ = sceneSession->GetCallingPid();
12590     callingWindowInfo.displayId_ = sceneSession->GetSessionProperty()->GetDisplayId();
12591     TLOGI(WmsLogTag::WMS_KEYBOARD, "callingWindowInfo: [id: %{public}d, pid: %{public}d, "
12592         "displayId: %{public}" PRIu64" , userId: %{public}d]", callingWindowInfo.windowId_,
12593         callingWindowInfo.callingPid_, callingWindowInfo.displayId_, callingWindowInfo.userId_);
12594     return WMError::WM_OK;
12595 }
12596 
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)12597 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
12598     int32_t x, int32_t y, std::vector<int32_t>& windowIds)
12599 {
12600     TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
12601           displayId, windowNumber, x, y);
12602     if (displayId == DISPLAY_ID_INVALID) {
12603         TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
12604         return WMError::WM_ERROR_INVALID_PARAM;
12605     }
12606     bool findAllWindow = windowNumber <= 0;
12607     bool checkPoint = (x >= 0 && y >= 0);
12608     std::string callerBundleName = SessionPermission::GetCallingBundleName();
12609     auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
12610         findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
12611         if (session == nullptr) {
12612             return false;
12613         }
12614         if (!findAllWindow && windowNumber == 0) {
12615             return true;
12616         }
12617         bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
12618         bool isSameDisplayId = session->GetSessionProperty()->GetDisplayId() == displayId;
12619         bool isRsVisible = session->GetRSVisible();
12620         WSRect windowRect = session->GetSessionRect();
12621         bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
12622         TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
12623                " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
12624                session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
12625                session->GetSessionProperty()->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
12626         if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
12627             return false;
12628         }
12629         windowIds.emplace_back(session->GetPersistentId());
12630         windowNumber--;
12631         return false;
12632     };
12633     return taskScheduler_->PostSyncTask([this, func = std::move(func)] {
12634         TraverseSessionTree(func, true);
12635         return WMError::WM_OK;
12636     }, __func__);
12637 }
12638 
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const12639 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
12640 {
12641     if (!infos.empty()) {
12642         TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
12643         return WMError::WM_ERROR_INVALID_PARAM;
12644     }
12645     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12646         TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
12647         return WMError::WM_ERROR_INVALID_PERMISSION;
12648     }
12649     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12650     for (const auto& iter : sceneSessionMap_) {
12651         auto& session = iter.second;
12652         if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
12653             continue;
12654         }
12655         MainWindowInfo info;
12656         auto abilityInfo = session->GetSessionInfo().abilityInfo;
12657         info.pid_ = session->GetCallingPid();
12658         info.bundleName_ = session->GetSessionInfo().bundleName_;
12659         info.persistentId_ = session->GetPersistentId();
12660         if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
12661             TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
12662             info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
12663             infos.push_back(info);
12664         } else if (abilityInfo != nullptr) {
12665             info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
12666             infos.push_back(info);
12667             TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
12668                 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
12669                 info.bundleName_.c_str(), info.bundleType_);
12670         }
12671     }
12672     return WMError::WM_OK;
12673 }
12674 
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)12675 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
12676     std::vector<int32_t>& clearFailedIds)
12677 {
12678     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12679         TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
12680         return WMError::WM_ERROR_INVALID_PERMISSION;
12681     }
12682     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12683         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12684         return WMError::WM_ERROR_INVALID_PERMISSION;
12685     }
12686     clearFailedIds.clear();
12687     for (const auto persistentId : persistentIds) {
12688         auto sceneSession = GetSceneSession(persistentId);
12689         if (sceneSession == nullptr) {
12690             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
12691             clearFailedIds.push_back(persistentId);
12692             continue;
12693         }
12694         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12695             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
12696             clearFailedIds.push_back(persistentId);
12697             continue;
12698         }
12699         sceneSession->Clear();
12700         TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
12701     }
12702     return WMError::WM_OK;
12703 }
12704 
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)12705 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
12706     bool enable)
12707 {
12708     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
12709         width, height, density, enable);
12710 
12711     DMHookInfo dmHookInfo;
12712     dmHookInfo.width_ = width;
12713     dmHookInfo.height_ = height;
12714     dmHookInfo.density_ = density;
12715     dmHookInfo.rotation_ = 0;
12716     dmHookInfo.enableHookRotation_ = false;
12717     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
12718     return WMError::WM_OK;
12719 }
12720 
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)12721 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
12722 {
12723     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
12724         "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
12725         hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
12726     if (enable && (uid <= 0 || hookInfo.width_ <= 0 || hookInfo.height_ <= 0 || hookInfo.density_ <= 0)) {
12727         TLOGE(WmsLogTag::WMS_LAYOUT, "App hookInfo param error.");
12728         return WMError::WM_ERROR_INVALID_PARAM;
12729     }
12730     DMHookInfo dmHookInfo;
12731     dmHookInfo.width_ = hookInfo.width_;
12732     dmHookInfo.height_ = hookInfo.height_;
12733     dmHookInfo.density_ = hookInfo.density_;
12734     dmHookInfo.rotation_ = hookInfo.rotation_;
12735     dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
12736     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
12737     return WMError::WM_OK;
12738 }
12739 
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)12740 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
12741 {
12742     SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
12743 }
12744 
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)12745 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
12746 {
12747     ScreenFoldData screenFoldData;
12748     WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
12749     if (ret != WMError::WM_OK) {
12750         return ret;
12751     }
12752     return CheckAndReportScreenFoldStatus(screenFoldData);
12753 }
12754 
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)12755 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
12756     ScreenFoldData& screenFoldData)
12757 {
12758     if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
12759         TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
12760         return WMError::WM_DO_NOTHING;
12761     }
12762 
12763     screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
12764     screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
12765     screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
12766     screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
12767     screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
12768     if (!screenFoldData.GetTypeCThermalWithUtil()) {
12769         TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
12770         return WMError::WM_DO_NOTHING;
12771     }
12772     AppExecFwk::ElementName element = {};
12773     WSError ret = GetFocusSessionElement(element);
12774     auto sceneSession = GetSceneSession(windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID));
12775     if (sceneSession == nullptr || ret != WSError::WS_OK) {
12776         TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
12777         return WMError::WM_DO_NOTHING;
12778     }
12779     screenFoldData.SetFocusedPkgName(element.GetURI());
12780     int32_t ret_z = HiSysEventWrite(
12781         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
12782         "FOCUS_WINDOW",
12783         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
12784         "PID", getpid(),
12785         "UID", getuid(),
12786         "BUNDLE_NAME", sceneSession->GetSessionInfo().bundleName_,
12787         "WINDOW_TYPE", static_cast<uint32_t>(sceneSession->GetWindowType()));
12788     if (ret_z != 0) {
12789         TLOGE(WmsLogTag::DMS, "Write FOCUS_WINDOW HiSysEvent error, ret_z: %{public}d.", ret_z);
12790     }
12791     return WMError::WM_OK;
12792 }
12793 
CheckAndReportScreenFoldStatus(ScreenFoldData & data)12794 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
12795 {
12796     static ScreenFoldData lastScreenHalfFoldData;
12797     if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
12798         lastScreenHalfFoldData = data;
12799         return WMError::WM_DO_NOTHING;
12800     }
12801     WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
12802     if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
12803         if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
12804             lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
12805         } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
12806             // if stay at half-fold less than 15s, combine this change with last
12807             data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
12808             data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
12809             data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
12810         }
12811         lastScreenHalfFoldData.SetInvalid();
12812     }
12813     WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
12814     return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
12815         currentScreenFoldStatusReportRet;
12816 }
12817 
12818 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)12819 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
12820 {
12821     if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
12822         return WMError::WM_DO_NOTHING;
12823     }
12824 
12825     int32_t ret = HiSysEventWrite(
12826         OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
12827         "FOLDSCREEN_STATE_CHANGE",
12828         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
12829         "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
12830         "LASTFOLDSTATE", data.currentScreenFoldStatus_,
12831         "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
12832         "STATE", -1,
12833         "TIME", data.currentScreenFoldStatusDuration_,
12834         "ROTATION", data.screenRotation_,
12835         "PACKAGE", data.focusedPackageName_,
12836         "ANGLE", data.postureAngle_,
12837         "TYPECTHERMAL", data.typeCThermal_,
12838         "SCREENTHERMAL", -1,
12839         "SCANGLE", -1,
12840         "ISTENT", -1);
12841     if (ret != 0) {
12842         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
12843         return WMError::WM_DO_NOTHING;
12844     }
12845     return WMError::WM_OK;
12846 }
12847 
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userId)12848 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userId)
12849 {
12850     if (currentUserId_ != static_cast<int32_t>(userId)) {
12851         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
12852             currentUserId_.load(), userId);
12853         return;
12854     }
12855     if (secExtensionData == nullptr) {
12856         TLOGE(WmsLogTag::WMS_EVENT, "invalid secExtensionData");
12857         return;
12858     }
12859     auto secSurfaceInfoMap = secExtensionData->GetSecData();
12860     auto task = [secSurfaceInfoMap]()-> WSError {
12861         SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
12862         return WSError::WS_OK;
12863     };
12864     taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
12865 }
12866 
RegisterSecSurfaceInfoListener()12867 void SceneSessionManager::RegisterSecSurfaceInfoListener()
12868 {
12869     auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
12870         this->UpdateSecSurfaceInfo(secExtensionData, userid);
12871     };
12872     TLOGI(WmsLogTag::WMS_EVENT, "in");
12873     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
12874         TLOGE(WmsLogTag::WMS_EVENT, "failed");
12875     }
12876 }
12877 
UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,uint64_t userId)12878 void SceneSessionManager::UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,
12879     uint64_t userId)
12880 {
12881     if (currentUserId_ != static_cast<int32_t>(userId)) {
12882         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
12883             currentUserId_.load(), userId);
12884         return;
12885     }
12886     if (constrainedModalUIExtData == nullptr) {
12887         TLOGE(WmsLogTag::WMS_EVENT, "invalid constrainedModalUIExtData");
12888         return;
12889     }
12890     auto constrainedModalUIExtInfoMap = constrainedModalUIExtData->GetSecData();
12891     auto task = [constrainedModalUIExtInfoMap]()-> WSError {
12892         SceneInputManager::GetInstance().UpdateConstrainedModalUIExtInfo(constrainedModalUIExtInfoMap);
12893         return WSError::WS_OK;
12894     };
12895     taskScheduler_->PostAsyncTask(task, "UpdateConstrainedModalUIExtInfo");
12896 }
12897 
RegisterConstrainedModalUIExtInfoListener()12898 void SceneSessionManager::RegisterConstrainedModalUIExtInfoListener()
12899 {
12900     auto callBack = [this](std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData, uint64_t userid) {
12901         this->UpdateConstrainedModalUIExtInfo(constrainedModalUIExtData, userid);
12902     };
12903     TLOGI(WmsLogTag::WMS_EVENT, "in");
12904     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack, true) != WM_OK) {
12905         TLOGE(WmsLogTag::WMS_EVENT, "failed");
12906     }
12907 }
12908 
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)12909 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
12910     const AppForceLandscapeConfig& config)
12911 {
12912     if (bundleName.empty()) {
12913         TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
12914         return WSError::WS_ERROR_NULLPTR;
12915     }
12916     std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
12917     appForceLandscapeMap_[bundleName] = config;
12918     TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
12919         bundleName.c_str(), config.mode_, config.homePage_.c_str());
12920     return WSError::WS_OK;
12921 }
12922 
GetAppForceLandscapeConfig(const std::string & bundleName)12923 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
12924 {
12925     if (bundleName.empty()) {
12926         return {};
12927     }
12928     std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
12929     if (appForceLandscapeMap_.empty() ||
12930         appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
12931         TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
12932         return {};
12933     }
12934     return appForceLandscapeMap_[bundleName];
12935 }
12936 
TerminateSessionByPersistentId(int32_t persistentId)12937 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
12938 {
12939     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
12940         TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
12941         return WMError::WM_ERROR_INVALID_PERMISSION;
12942     }
12943     if (!SessionPermission::IsSystemAppCall()) {
12944         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
12945         return WMError::WM_ERROR_NOT_SYSTEM_APP;
12946     }
12947     auto sceneSession = GetSceneSession(persistentId);
12948     if (sceneSession == nullptr) {
12949         TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
12950         return WMError::WM_ERROR_INVALID_PARAM;
12951     }
12952     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12953         TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
12954         return WMError::WM_ERROR_INVALID_PARAM;
12955     }
12956     sceneSession->Clear(true);
12957     TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
12958     return WMError::WM_OK;
12959 }
12960 
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)12961 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
12962 {
12963     rootSceneProcessBackEventFunc_ = processBackEventFunc;
12964     TLOGI(WmsLogTag::WMS_EVENT, "end");
12965 }
12966 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)12967 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
12968     const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
12969 {
12970     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12971         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
12972         return WMError::WM_ERROR_INVALID_PERMISSION;
12973     }
12974 
12975     surfaceNodeIds.clear();
12976     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
12977     for (auto persistentId : persistentIds) {
12978         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "convert wid:%{public}d", persistentId);
12979         auto sceneSession = GetSceneSession(persistentId);
12980         if (sceneSession == nullptr) {
12981             continue;
12982         }
12983         auto callingPid = sceneSession->GetCallingPid();
12984         auto surfaceNode = sceneSession->GetSurfaceNode();
12985         if (surfaceNode != nullptr && callingPid == pid) {
12986             surfaceNodeIds.push_back(surfaceNode->GetId());
12987             auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
12988             if (leashWinSurfaceNode != nullptr) {
12989                 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
12990                 surfaceNodeIds.push_back(persistentId);
12991             }
12992         }
12993     }
12994 
12995     return WMError::WM_OK;
12996 }
12997 
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)12998 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
12999 {
13000     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
13001     auto task = [this, func] {
13002         closeTargetFloatWindowFunc_ = func;
13003     };
13004     taskScheduler_->PostTask(task, __func__);
13005 }
13006 
CloseTargetFloatWindow(const std::string & bundleName)13007 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
13008 {
13009     if (!SessionPermission::IsSystemServiceCalling(false)) {
13010         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
13011         return WMError::WM_ERROR_INVALID_PERMISSION;
13012     }
13013     auto task = [this, bundleName] {
13014         if (closeTargetFloatWindowFunc_) {
13015             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
13016             closeTargetFloatWindowFunc_(bundleName);
13017         }
13018     };
13019     taskScheduler_->PostTask(task, __func__);
13020     return WMError::WM_OK;
13021 }
13022 
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)13023 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
13024 {
13025     SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
13026 }
13027 
CloseTargetPiPWindow(const std::string & bundleName)13028 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
13029 {
13030     if (!SessionPermission::IsSystemServiceCalling(false)) {
13031         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
13032         return WMError::WM_ERROR_INVALID_PERMISSION;
13033     }
13034     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13035     for (const auto& iter : sceneSessionMap_) {
13036         auto& session = iter.second;
13037         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
13038             session->GetSessionInfo().bundleName_ == bundleName) {
13039             session->NotifyCloseExistPipWindow();
13040             break;
13041         }
13042     }
13043     return WMError::WM_OK;
13044 }
13045 
GetCurrentPiPWindowInfo(std::string & bundleName)13046 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
13047 {
13048     if (!SessionPermission::IsSystemServiceCalling(false)) {
13049         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
13050         return WMError::WM_ERROR_INVALID_PERMISSION;
13051     }
13052     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13053     for (const auto& iter : sceneSessionMap_) {
13054         auto& session = iter.second;
13055         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
13056             bundleName = session->GetSessionInfo().bundleName_;
13057             return WMError::WM_OK;
13058         }
13059     }
13060     TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
13061     return WMError::WM_OK;
13062 }
13063 
RefreshPcZOrderList(uint32_t startZOrder,std::vector<int32_t> && persistentIds)13064 void SceneSessionManager::RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)
13065 {
13066     const char* const where = __func__;
13067     auto task = [this, startZOrder, persistentIds = std::move(persistentIds), where] {
13068         std::ostringstream oss;
13069         oss << "[";
13070         for (size_t i = 0; i < persistentIds.size(); i++) {
13071             int32_t persistentId = persistentIds[i];
13072             oss << persistentId;
13073             if (i < persistentIds.size() - 1) {
13074                 oss << ",";
13075             }
13076             auto sceneSession = GetSceneSession(persistentId);
13077             if (sceneSession == nullptr) {
13078                 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr persistentId=%{public}d", persistentId);
13079                 continue;
13080             }
13081             if (i > UINT32_MAX - startZOrder) {
13082                 TLOGNE(WmsLogTag::WMS_LAYOUT, "Z order overflow, stop refresh");
13083                 break;
13084             }
13085             sceneSession->SetPcScenePanel(true);
13086             sceneSession->UpdatePCZOrderAndMarkDirty(i + startZOrder);
13087         }
13088         oss << "]";
13089         TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: %{public}s", where, oss.str().c_str());
13090         return WSError::WS_OK;
13091     };
13092     taskScheduler_->PostTask(task, __func__);
13093 }
13094 
SkipSnapshotForAppProcess(int32_t pid,bool skip)13095 WMError SceneSessionManager::SkipSnapshotForAppProcess(int32_t pid, bool skip)
13096 {
13097     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13098         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13099         return WMError::WM_ERROR_INVALID_PERMISSION;
13100     }
13101     if (pid < 0) {
13102         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid pid!");
13103         return WMError::WM_ERROR_INVALID_PARAM;
13104     }
13105     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d, skip:%{public}u", pid, skip);
13106     auto task = [this, pid, skip]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
13107         if (skip) {
13108             snapshotSkipPidSet_.insert(pid);
13109         } else {
13110             snapshotSkipPidSet_.erase(pid);
13111         }
13112         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13113         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
13114             if (sceneSession == nullptr) {
13115                 continue;
13116             }
13117             if (pid == sceneSession->GetCallingPid()) {
13118                 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "send rs set snapshot skip, persistentId:%{public}d, skip:%{public}u",
13119                     persistentId, skip);
13120                 sceneSession->SetSnapshotSkip(skip);
13121             }
13122         }
13123     };
13124     taskScheduler_->PostTask(task, "SkipSnapshotForAppProcess");
13125     return WMError::WM_OK;
13126 }
13127 
RemoveProcessSnapshotSkip(int32_t pid)13128 void SceneSessionManager::RemoveProcessSnapshotSkip(int32_t pid)
13129 {
13130     if (snapshotSkipPidSet_.erase(pid) != 0) {
13131         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from snapshot skip pid set. pid:%{public}d", pid);
13132     }
13133 }
13134 
SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession> & sceneSession)13135 void SceneSessionManager::SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)
13136 {
13137     auto callingPid = sceneSession->GetCallingPid();
13138     if (snapshotSkipPidSet_.find(callingPid) != snapshotSkipPidSet_.end()) {
13139         sceneSession->SetSnapshotSkip(true);
13140     }
13141 }
13142 
SkipSnapshotByUserIdAndBundleNames(int32_t userId,const std::vector<std::string> & bundleNameList)13143 WMError SceneSessionManager::SkipSnapshotByUserIdAndBundleNames(int32_t userId,
13144     const std::vector<std::string>& bundleNameList)
13145 {
13146     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13147         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
13148         return WMError::WM_ERROR_INVALID_PERMISSION;
13149     }
13150     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "userId:%{public}d", userId);
13151     auto task = [this, userId, bundleNameList]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
13152         snapshotSkipBundleNameSet_.clear();
13153         for (auto& bundleName : bundleNameList) {
13154             snapshotSkipBundleNameSet_.insert(std::move(bundleName));
13155         }
13156         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13157         for (const auto& [_, sceneSession] : sceneSessionMap_) {
13158             if (sceneSession == nullptr) {
13159                 continue;
13160             }
13161             const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
13162             if (snapshotSkipBundleNameSet_.find(bundleName) != snapshotSkipBundleNameSet_.end()) {
13163                 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
13164                     bundleName.c_str());
13165                 sceneSession->SetSnapshotSkip(true);
13166                 continue;
13167             }
13168             sceneSession->SetSnapshotSkip(false);
13169         }
13170     };
13171     taskScheduler_->PostTask(task, __func__);
13172     return WMError::WM_OK;
13173 }
13174 
SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession> & sceneSession)13175 void SceneSessionManager::SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)
13176 {
13177     const std::string& name = sceneSession->GetSessionInfo().bundleName_;
13178     if (snapshotSkipBundleNameSet_.find(name) != snapshotSkipBundleNameSet_.end()) {
13179         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
13180             name.c_str());
13181         sceneSession->SetSnapshotSkip(true);
13182     }
13183 }
13184 
SetProcessWatermark(int32_t pid,const std::string & watermarkName,bool isEnabled)13185 WMError SceneSessionManager::SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)
13186 {
13187     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13188         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13189         return WMError::WM_ERROR_INVALID_PERMISSION;
13190     }
13191     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "pid:%{public}d, watermarkName:%{public}s, isEnabled:%{public}u",
13192         pid, watermarkName.c_str(), isEnabled);
13193     if (isEnabled && watermarkName.empty()) {
13194         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "watermarkName is empty!");
13195         return WMError::WM_ERROR_INVALID_PARAM;
13196     }
13197     auto task = [this, pid, watermarkName, isEnabled] {
13198         if (isEnabled) {
13199             processWatermarkPidMap_.insert_or_assign(pid, watermarkName);
13200         } else {
13201             processWatermarkPidMap_.erase(pid);
13202         }
13203 
13204         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13205         for (const auto& [_, sceneSession] : sceneSessionMap_) {
13206             if (sceneSession == nullptr) {
13207                 continue;
13208             }
13209             if (pid == sceneSession->GetCallingPid()) {
13210                 sceneSession->SetWatermarkEnabled(watermarkName, isEnabled);
13211             }
13212         }
13213     };
13214     taskScheduler_->PostTask(task, __func__);
13215     return WMError::WM_OK;
13216 }
13217 
SetSessionWatermarkForAppProcess(const sptr<SceneSession> & sceneSession)13218 bool SceneSessionManager::SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)
13219 {
13220     if (auto iter = processWatermarkPidMap_.find(sceneSession->GetCallingPid());
13221         iter != processWatermarkPidMap_.end()) {
13222         sceneSession->SetWatermarkEnabled(iter->second, true);
13223         return true;
13224     }
13225     return false;
13226 }
13227 
RemoveProcessWatermarkPid(int32_t pid)13228 void SceneSessionManager::RemoveProcessWatermarkPid(int32_t pid)
13229 {
13230     if (processWatermarkPidMap_.find(pid) != processWatermarkPidMap_.end()) {
13231         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from watermark pid map. pid:%{public}d", pid);
13232         processWatermarkPidMap_.erase(pid);
13233     }
13234 }
13235 
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)13236 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
13237 {
13238     if (!SessionPermission::IsSystemServiceCalling()) {
13239         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
13240         return WMError::WM_ERROR_INVALID_PERMISSION;
13241     }
13242     const char* const where = __func__;
13243     auto task = [this, persistentId, &hostWindowId, where]() {
13244         hostWindowId = INVALID_WINDOW_ID;
13245         sptr<Session> session = GetSceneSession(persistentId);
13246         while (session && SessionHelper::IsSubWindow(session->GetWindowType())) {
13247             session = session->GetParentSession();
13248         }
13249         if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
13250             hostWindowId = session->GetPersistentId();
13251         }
13252         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
13253             where, persistentId, hostWindowId);
13254         return WMError::WM_OK;
13255     };
13256     return taskScheduler_->PostSyncTask(task, where);
13257 }
13258 
GetMaxInstanceCount(const std::string & bundleName)13259 int32_t SceneSessionManager::GetMaxInstanceCount(const std::string& bundleName)
13260 {
13261     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13262         return MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
13263     } else {
13264         return 0;
13265     }
13266 }
13267 
GetInstanceCount(const std::string & bundleName)13268 int32_t SceneSessionManager::GetInstanceCount(const std::string& bundleName)
13269 {
13270     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13271         return MultiInstanceManager::GetInstance().GetInstanceCount(bundleName);
13272     } else {
13273         return 0;
13274     }
13275 }
13276 
GetLastInstanceKey(const std::string & bundleName)13277 std::string SceneSessionManager::GetLastInstanceKey(const std::string& bundleName)
13278 {
13279     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13280         return MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
13281     } else {
13282         return "";
13283     }
13284 }
13285 
RefreshAppInfo(const std::string & bundleName)13286 void SceneSessionManager::RefreshAppInfo(const std::string& bundleName)
13287 {
13288     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13289         MultiInstanceManager::GetInstance().RefreshAppInfo(bundleName);
13290     }
13291     AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
13292 }
13293 
UpdateScreenLockStatusForApp(const std::string & bundleName,bool isRelease)13294 WMError SceneSessionManager::UpdateScreenLockStatusForApp(const std::string& bundleName, bool isRelease)
13295 {
13296     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13297         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13298         return WMError::WM_ERROR_INVALID_PERMISSION;
13299     }
13300 #ifdef POWER_MANAGER_ENABLE
13301     if (isRelease) {
13302         return ReleaseScreenLockForApp(bundleName);
13303     } else {
13304         return RelockScreenLockForApp(bundleName);
13305     }
13306 #else
13307     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Can not find the sub system of PowerMgr");
13308     return WMError::WM_OK;
13309 #endif
13310 }
13311 
ReleaseScreenLockForApp(const std::string & bundleName)13312 WMError SceneSessionManager::ReleaseScreenLockForApp(const std::string& bundleName)
13313 {
13314     std::vector<sptr<SceneSession>> sessionsToReleaseScreenLock;
13315     GetAllSessionsToReleaseScreenLock(sessionsToReleaseScreenLock, bundleName);
13316     auto task = [this, bundleName, sessionsToReleaseScreenLock] {
13317         for (const auto& sceneSession : sessionsToReleaseScreenLock) {
13318             if (sceneSession->keepScreenLock_ == nullptr || !sceneSession->keepScreenLock_->IsUsed()) {
13319                 continue;
13320             }
13321             auto res = sceneSession->keepScreenLock_->UnLock();
13322             if (res != ERR_OK) {
13323                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE,
13324                     "release screenlock failed, window:[%{public}d, %{public}s], err:%{public}d",
13325                     sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str(), res);
13326                 continue;
13327             }
13328             auto [iter, emplaced] = releasedScreenLockMap_.try_emplace(bundleName, std::unordered_set<int32_t>{});
13329             iter->second.insert(sceneSession->GetPersistentId());
13330             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "release screenlock success, window:[%{public}d, %{public}s]",
13331                 sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str());
13332         }
13333         return WMError::WM_OK;
13334     };
13335     return taskScheduler_->PostSyncTask(task, __func__);
13336 }
13337 
GetAllSessionsToReleaseScreenLock(std::vector<sptr<SceneSession>> & sessionsToReleaseScreenLock,const std::string & bundleName)13338 void SceneSessionManager::GetAllSessionsToReleaseScreenLock(
13339     std::vector<sptr<SceneSession>>& sessionsToReleaseScreenLock, const std::string& bundleName) {
13340     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13341     for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
13342         if (sceneSession->GetSessionInfo().bundleName_ == bundleName && sceneSession->keepScreenLock_ != nullptr) {
13343             sessionsToReleaseScreenLock.push_back(sceneSession);
13344         }
13345     }
13346 }
13347 
RelockScreenLockForApp(const std::string & bundleName)13348 WMError SceneSessionManager::RelockScreenLockForApp(const std::string& bundleName)
13349 {
13350     auto task = [this, bundleName] {
13351         auto iter = releasedScreenLockMap_.find(bundleName);
13352         if (iter == releasedScreenLockMap_.end()) {
13353             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: not found in map", bundleName.c_str());
13354             return WMError::WM_ERROR_INVALID_OPERATION;
13355         }
13356         const auto& persistentIds = iter->second;
13357         for (const int32_t persistentId : persistentIds) {
13358             sptr<SceneSession> sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
13359             if (sceneSession == nullptr) {
13360                 continue;
13361             }
13362             auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
13363             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(
13364                 sceneSession->GetScreenId());
13365             if (screenSession) {
13366                 sourceMode = screenSession->GetSourceMode();
13367             }
13368             if (sceneSession->IsKeepScreenOn() && IsSessionVisibleForeground(sceneSession) &&
13369                 sourceMode != ScreenSourceMode::SCREEN_UNIQUE && sceneSession->keepScreenLock_ != nullptr) {
13370                 auto res = sceneSession->keepScreenLock_->Lock();
13371                 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "relock screenlock, window: [%{public}d, %{public}s], res:%{public}d",
13372                     persistentId, sceneSession->GetWindowName().c_str(), res);
13373             }
13374         }
13375         releasedScreenLockMap_.erase(bundleName);
13376         return WMError::WM_OK;
13377     };
13378     return taskScheduler_->PostSyncTask(task, __func__);
13379 }
13380 
IsPcWindow(bool & isPcWindow)13381 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
13382 {
13383     isPcWindow = systemConfig_.IsPcWindow();
13384     return WMError::WM_OK;
13385 }
13386 
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)13387 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
13388 {
13389     isPcOrPadFreeMultiWindowMode = (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode());
13390     return WMError::WM_OK;
13391 }
13392 
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)13393 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
13394     std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
13395 {
13396     if (!SessionPermission::IsSystemCalling()) {
13397         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13398         return WMError::WM_ERROR_INVALID_PERMISSION;
13399     }
13400 
13401     auto task = [this, windowIds, &windowDisplayIdMap] {
13402         for (const uint64_t windowId : windowIds) {
13403             sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
13404             if (session == nullptr) {
13405                 continue;
13406             }
13407             DisplayId displayId = session->GetSessionProperty()->GetDisplayId();
13408             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
13409                 windowId, displayId);
13410             windowDisplayIdMap.insert({windowId, displayId});
13411         }
13412         return WMError::WM_OK;
13413     };
13414     return taskScheduler_->PostSyncTask(task, __func__);
13415 }
13416 
IsLastFrameLayoutFinished(bool & isLayoutFinished)13417 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
13418 {
13419     if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
13420         TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
13421         return WSError::WS_ERROR_NULLPTR;
13422     }
13423     isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
13424     return WSError::WS_OK;
13425 }
13426 
IsWindowRectAutoSave(const std::string & key,bool & enabled,int persistentId)13427 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled, int persistentId)
13428 {
13429     auto sceneSession = GetSceneSession(persistentId);
13430     if (sceneSession == nullptr) {
13431         TLOGE(WmsLogTag::WMS_MAIN, "sceneSession %{public}d is nullptr", persistentId);
13432         return WMError::WM_ERROR_INVALID_SESSION;
13433     }
13434     std::string specifiedKey = key;
13435     if (sceneSession->GetSessionProperty()->GetIsSaveBySpecifiedFlag()) {
13436         specifiedKey = key + sceneSession->GetSessionInfo().specifiedFlag_;
13437     }
13438     TLOGD(WmsLogTag::WMS_MAIN, "windowId: %{public}d, specifiedKey: %{public}s", persistentId, specifiedKey.c_str());
13439     std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
13440     if (auto iter = isWindowRectAutoSaveMap_.find(specifiedKey); iter != isWindowRectAutoSaveMap_.end()) {
13441         enabled = iter->second;
13442     } else {
13443         enabled = false;
13444     }
13445     return WMError::WM_OK;
13446 }
13447 
SetIsWindowRectAutoSave(const std::string & key,bool enabled)13448 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled)
13449 {
13450     std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
13451     if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
13452         if (!enabled) {
13453             isWindowRectAutoSaveMap_.erase(key);
13454         } else {
13455             iter->second = enabled;
13456         }
13457     } else {
13458         if (enabled) {
13459             isWindowRectAutoSaveMap_.insert({key, enabled});
13460         }
13461     }
13462 }
13463 
MinimizeMainSession(const std::string & bundleName,int32_t appIndex,int32_t userId)13464 WMError SceneSessionManager::MinimizeMainSession(const std::string& bundleName, int32_t appIndex, int32_t userId)
13465 {
13466     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13467         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13468         return WMError::WM_ERROR_INVALID_PERMISSION;
13469     }
13470     if ((currentUserId_ != userId && currentUserId_ != DEFAULT_USERID) ||
13471         (currentUserId_ == DEFAULT_USERID && userId != GetUserIdByUid(getuid()))) {
13472         TLOGW(WmsLogTag::WMS_LIFE, "currentUserId:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
13473             currentUserId_.load(), userId, GetUserIdByUid(getuid()));
13474         return WMError::WM_ERROR_INVALID_OPERATION;
13475     }
13476     const char* const where = __func__;
13477     taskScheduler_->PostAsyncTask([this, bundleName, appIndex, where] {
13478         std::vector<sptr<SceneSession>> mainSessions;
13479         GetMainSessionByBundleNameAndAppIndex(bundleName, appIndex, mainSessions);
13480         if (mainSessions.empty()) {
13481             TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, not found any main session", where);
13482             return;
13483         }
13484         for (const auto& session : mainSessions) {
13485             session->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
13486             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d.", where, session->GetPersistentId());
13487         }
13488     }, __func__);
13489     return WMError::WM_OK;
13490 }
13491 
ShiftAppWindowPointerEvent(int32_t sourcePersistentId,int32_t targetPersistentId)13492 WMError SceneSessionManager::ShiftAppWindowPointerEvent(int32_t sourcePersistentId, int32_t targetPersistentId)
13493 {
13494     TLOGD(WmsLogTag::WMS_PC, "sourcePersistentId %{public}d targetPersistentId %{public}d",
13495         sourcePersistentId, targetPersistentId);
13496     if (!(systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode())) {
13497         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
13498     }
13499     if (sourcePersistentId == targetPersistentId) {
13500         return WMError::WM_ERROR_INVALID_CALLING;
13501     }
13502     sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
13503     if (sourceSession == nullptr) {
13504         TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is nullptr", sourcePersistentId);
13505         return WMError::WM_ERROR_INVALID_SESSION;
13506     }
13507     if (!WindowHelper::IsAppWindow(sourceSession->GetWindowType())) {
13508         TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is not app window", sourcePersistentId);
13509         return WMError::WM_ERROR_INVALID_CALLING;
13510     }
13511     sptr<SceneSession> targetSession = GetSceneSession(targetPersistentId);
13512     if (targetSession == nullptr) {
13513         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is nullptr", targetPersistentId);
13514         return WMError::WM_ERROR_INVALID_SESSION;
13515     }
13516     if (!WindowHelper::IsAppWindow(targetSession->GetWindowType())) {
13517         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not app window", targetPersistentId);
13518         return WMError::WM_ERROR_INVALID_CALLING;
13519     }
13520     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
13521         TLOGE(WmsLogTag::WMS_PC, "verify bundle failed, source name is %{public}s but target name is %{public}s",
13522             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
13523         return WMError::WM_ERROR_INVALID_CALLING;
13524     }
13525     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
13526         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not same bundle as calling", targetPersistentId);
13527         return WMError::WM_ERROR_INVALID_CALLING;
13528     }
13529     int32_t callingPid = IPCSkeleton::GetCallingPid();
13530     if (callingPid != targetSession->GetCallingPid()) {
13531         TLOGE(WmsLogTag::WMS_PC, "permission denied, not call by the same process");
13532         return WMError::WM_ERROR_INVALID_CALLING;
13533     }
13534     return ShiftAppWindowPointerEventInner(sourcePersistentId, targetPersistentId,
13535         targetSession->GetSessionProperty()->GetDisplayId());
13536 }
13537 
ShiftAppWindowPointerEventInner(int32_t sourceWindowId,int32_t targetWindowId,DisplayId targetDisplayId)13538 WMError SceneSessionManager::ShiftAppWindowPointerEventInner(
13539     int32_t sourceWindowId, int32_t targetWindowId, DisplayId targetDisplayId)
13540 {
13541     return taskScheduler_->PostSyncTask([sourceWindowId, targetWindowId, targetDisplayId] {
13542         auto display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
13543     	float vpr = 1.5f; // 1.5f: default virtual pixel ratio
13544     	if (display) {
13545         	vpr = display->GetVirtualPixelRatio();
13546     	}
13547     	int32_t outside = static_cast<int32_t>(HOTZONE_TOUCH * vpr * 2); // double touch hotzone
13548     	MMI::ShiftWindowParam param;
13549     	param.sourceWindowId = sourceWindowId;
13550     	param.targetWindowId = targetWindowId;
13551     	param.x = -outside;
13552     	param.y = -outside;
13553         int ret = MMI::InputManager::GetInstance()->ShiftAppPointerEvent(param, true);
13554         TLOGNI(WmsLogTag::WMS_PC, "sourceWindowId %{public}d targetWindowId %{public}d ret %{public}d",
13555             param.sourceWindowId, param.targetWindowId, ret);
13556         return ret == 0 ? WMError::WM_OK : WMError::WM_ERROR_INVALID_CALLING;
13557     }, __func__);
13558 }
13559 
LockSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,bool isLock)13560 WMError SceneSessionManager::LockSessionByAbilityInfo(const AbilityInfoBase& abilityInfo, bool isLock)
13561 {
13562     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13563         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13564         return WMError::WM_ERROR_INVALID_PERMISSION;
13565     }
13566     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
13567         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
13568         return WMError::WM_ERROR_INVALID_PERMISSION;
13569     }
13570     TLOGI(WmsLogTag::WMS_LIFE,
13571         "bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s appIndex:%{public}d isLock:%{public}d",
13572         abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.abilityName.c_str(),
13573         abilityInfo.appIndex, isLock);
13574     if (!abilityInfo.IsValid()) {
13575         TLOGE(WmsLogTag::WMS_LIFE, "abilityInfo not valid");
13576         return WMError::WM_ERROR_INVALID_PARAM;
13577     }
13578     taskScheduler_->PostAsyncTask([this, abilityInfo, isLock, where = __func__] {
13579         std::vector<sptr<SceneSession>> mainSessions;
13580         GetMainSessionByAbilityInfo(abilityInfo, mainSessions);
13581         if (!mainSessions.empty()) {
13582             for (const auto& mainSession : mainSessions) {
13583                 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, set isLockedState true, persistentId:%{public}d",
13584                     where, mainSession->GetPersistentId());
13585                 mainSession->NotifySessionLockStateChange(isLock);
13586             }
13587             if (isLock) {
13588                 return;
13589             }
13590         }
13591         if (isLock) {
13592             if (sessionLockedStateCacheSet_.size() > MAX_LOCK_STATUS_CACHE_SIZE) {
13593                 auto iter = sessionLockedStateCacheSet_.begin();
13594                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, reach max erase begin:%{public}s", where, (*iter).c_str());
13595                 sessionLockedStateCacheSet_.erase(iter);
13596             }
13597             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, update isLockedState into cache set", where);
13598             sessionLockedStateCacheSet_.insert(abilityInfo.ToKeyString());
13599         } else {
13600             sessionLockedStateCacheSet_.erase(abilityInfo.ToKeyString());
13601         }
13602     }, __func__);
13603     return WMError::WM_OK;
13604 }
13605 
HasFloatingWindowForeground(const sptr<IRemoteObject> & abilityToken,bool & hasOrNot)13606 WMError SceneSessionManager::HasFloatingWindowForeground(const sptr<IRemoteObject>& abilityToken, bool& hasOrNot)
13607 {
13608     if (!abilityToken) {
13609         TLOGE(WmsLogTag::WMS_SYSTEM, "AbilityToken is null");
13610         return WMError::WM_ERROR_NULLPTR;
13611     }
13612     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13613         TLOGE(WmsLogTag::WMS_SYSTEM, "Permission denied, only for SA");
13614         return WMError::WM_ERROR_INVALID_PERMISSION;
13615     }
13616 
13617     return taskScheduler_->PostSyncTask([this, &abilityToken, &hasOrNot, where = __func__] {
13618         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13619         for (const auto& [_, session] : sceneSessionMap_) {
13620             if (session && session->GetAbilityToken() == abilityToken &&
13621                 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && session->IsSessionForeground()) {
13622                 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s found", where);
13623                 hasOrNot = true;
13624                 return WMError::WM_OK;
13625             }
13626         }
13627         TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s not found", where);
13628         hasOrNot = false;
13629         return WMError::WM_OK;
13630     }, __func__);
13631 }
13632 
SetStatusBarAvoidHeight(int32_t height)13633 void SceneSessionManager::SetStatusBarAvoidHeight(int32_t height)
13634 {
13635     const char* const where = __func__;
13636     auto task = [this, where, height] {
13637         statusBarAvoidHeight_ = height >= 0 ? height : INVALID_STATUS_BAR_AVOID_HEIGHT;
13638         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s, height %{public}d", where, statusBarAvoidHeight_);
13639         return WMError::WM_OK;
13640     };
13641     taskScheduler_->PostSyncTask(task, where);
13642 }
13643 
GetStatusBarAvoidHeight(WSRect & barArea)13644 void SceneSessionManager::GetStatusBarAvoidHeight(WSRect& barArea)
13645 {
13646     barArea.height_ = statusBarAvoidHeight_ == INVALID_STATUS_BAR_AVOID_HEIGHT ?
13647         barArea.height_ : statusBarAvoidHeight_;
13648 }
13649 
CloneWindow(int32_t fromPersistentId,int32_t toPersistentId)13650 WSError SceneSessionManager::CloneWindow(int32_t fromPersistentId, int32_t toPersistentId)
13651 {
13652     return taskScheduler_->PostSyncTask([this, fromPersistentId, toPersistentId]() {
13653         auto toSceneSession = GetSceneSession(toPersistentId);
13654         if (toSceneSession == nullptr) {
13655             TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", toPersistentId);
13656             return WSError::WS_ERROR_NULLPTR;
13657         }
13658         NodeId nodeId = INVALID_NODEID;
13659         if (fromPersistentId >= 0) { // if fromPersistentId < 0, excute CloneWindow(0) to cancel cloneWindow
13660             if (auto fromSceneSession = GetSceneSession(fromPersistentId)) {
13661                 if (auto surfaceNode = fromSceneSession->GetSurfaceNode()) {
13662                     nodeId = surfaceNode->GetId();
13663                 }
13664             } else {
13665                 TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", fromPersistentId);
13666                 return WSError::WS_ERROR_NULLPTR;
13667             }
13668         }
13669         toSceneSession->CloneWindow(nodeId);
13670         TLOGNI(WmsLogTag::WMS_PC, "fromSurfaceId: %{public}" PRIu64, nodeId);
13671         return WSError::WS_OK;
13672     }, __func__);
13673 }
13674 
UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty> & property)13675 DisplayId SceneSessionManager::UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty>& property)
13676 {
13677     auto initClientDisplayId = DEFAULT_DISPLAY_ID;
13678     //  SubWindow
13679     if (auto parentSession = GetSceneSession(property->GetParentPersistentId())) {
13680         if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
13681             property->SetDisplayId(DEFAULT_DISPLAY_ID);
13682             initClientDisplayId = parentSession->GetClientDisplayId();
13683         }
13684     }
13685     // SystemWindow
13686     if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
13687         property->SetDisplayId(DEFAULT_DISPLAY_ID);
13688         initClientDisplayId = VIRTUAL_DISPLAY_ID;
13689     }
13690     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winName:%{public}s, type:%{public}u, displayId:%{public}" PRIu64
13691         ", clientDisplayId: %{public}" PRIu64, property->GetWindowName().c_str(), property->GetWindowType(),
13692         property->GetDisplayId(), initClientDisplayId);
13693     return initClientDisplayId;
13694 }
13695 
UpdateSessionDisplayIdBySessionInfo(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)13696 void SceneSessionManager::UpdateSessionDisplayIdBySessionInfo(
13697     sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
13698 {
13699     if (sceneSession->GetScreenId() == VIRTUAL_DISPLAY_ID &&
13700         sceneSession->GetSessionProperty()->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
13701         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s move display %{public}" PRIu64 " from %{public}" PRIu64,
13702             sessionInfo.bundleName_.c_str(), sessionInfo.screenId_, VIRTUAL_DISPLAY_ID);
13703         sceneSession->SetScreenId(sessionInfo.screenId_);
13704         sceneSession->GetSessionProperty()->SetDisplayId(sessionInfo.screenId_);
13705     }
13706 }
13707 
RemoveLifeCycleTaskByPersistentId(int32_t persistentId,const LifeCycleTaskType taskType)13708 void SceneSessionManager::RemoveLifeCycleTaskByPersistentId(int32_t persistentId,
13709     const LifeCycleTaskType taskType)
13710 {
13711     auto sceneSession = GetSceneSession(persistentId);
13712     if (sceneSession == nullptr) {
13713         TLOGE(WmsLogTag::WMS_LIFE, "session:%{public}d is nullptr", persistentId);
13714         return;
13715     }
13716     sceneSession->RemoveLifeCycleTask(taskType);
13717 }
13718 
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<int32_t> & persistentIdList)13719 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
13720     const std::vector<int32_t>& persistentIdList)
13721 {
13722     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13723         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13724         return WMError::WM_ERROR_INVALID_PERMISSION;
13725     }
13726     if (persistentIdList.empty()) {
13727         TLOGE(WmsLogTag::WMS_LIFE, "persistentIdList is empty!");
13728         return WMError::WM_ERROR_INVALID_PARAM;
13729     }
13730     if (listener == nullptr) {
13731         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
13732         return WMError::WM_ERROR_INVALID_PARAM;
13733     }
13734     taskScheduler_->PostAsyncTask([this, listener, persistentIdList, where = __func__] {
13735         WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, persistentIdList);
13736         TLOGI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
13737     }, __func__);
13738     return WMError::WM_OK;
13739 }
13740 
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<std::string> & bundleNameList)13741 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
13742     const std::vector<std::string>& bundleNameList)
13743 {
13744     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13745         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13746         return WMError::WM_ERROR_INVALID_PERMISSION;
13747     }
13748     if (listener == nullptr) {
13749         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
13750         return WMError::WM_ERROR_INVALID_PARAM;
13751     }
13752     taskScheduler_->PostAsyncTask([this, listener, bundleNameList, where = __func__] {
13753         WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, bundleNameList);
13754         TLOGI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
13755     }, __func__);
13756     return WMError::WM_OK;
13757 }
13758 
UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener)13759 WMError SceneSessionManager::UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener)
13760 {
13761     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13762         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13763         return WMError::WM_ERROR_INVALID_PERMISSION;
13764     }
13765     if (listener == nullptr) {
13766         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
13767         return WMError::WM_ERROR_INVALID_PARAM;
13768     }
13769     taskScheduler_->PostAsyncTask([this, listener, where = __func__] {
13770         WMError ret = listenerController_->UnregisterSessionLifecycleListener(listener);
13771         TLOGI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
13772     }, __func__);
13773     return WMError::WM_OK;
13774 }
13775 
SetParentWindowInner(const sptr<SceneSession> & subSession,const sptr<SceneSession> & oldParentSession,const sptr<SceneSession> & newParentSession)13776 WMError SceneSessionManager::SetParentWindowInner(const sptr<SceneSession>& subSession,
13777     const sptr<SceneSession>& oldParentSession, const sptr<SceneSession>& newParentSession)
13778 {
13779     uint32_t oldSubWindowLevel = oldParentSession->GetSessionProperty()->GetSubWindowLevel();
13780     uint32_t newSubWindowLevel = newParentSession->GetSessionProperty()->GetSubWindowLevel();
13781     if (oldSubWindowLevel < newSubWindowLevel &&
13782         subSession->GetMaxSubWindowLevel() + newSubWindowLevel > MAX_SUB_WINDOW_LEVEL) {
13783         TLOGE(WmsLogTag::WMS_SUB, "newParentSession sub level limit");
13784         return WMError::WM_ERROR_INVALID_PARENT;
13785     }
13786     int32_t oldParentWindowId = oldParentSession->GetPersistentId();
13787     int32_t newParentWindowId = newParentSession->GetPersistentId();
13788     subSession->NotifySetParentSession(oldParentWindowId, newParentWindowId);
13789     int32_t subWindowId = subSession->GetPersistentId();
13790     oldParentSession->RemoveSubSession(subWindowId);
13791     newParentSession->AddSubSession(subSession);
13792     subSession->SetParentSession(newParentSession);
13793     subSession->SetParentPersistentId(newParentWindowId);
13794     subSession->UpdateSubWindowLevel(newSubWindowLevel + 1);
13795     if (oldSubWindowLevel == 0) {
13796         oldParentSession->UnregisterNotifySurfaceBoundsChangeFunc(subWindowId);
13797         if (newSubWindowLevel == 0 && subSession->GetIsFollowParentLayout()) {
13798             subSession->SetFollowParentWindowLayoutEnabled(true);
13799         }
13800     }
13801     return WMError::WM_OK;
13802 }
13803 
SetParentWindow(int32_t subWindowId,int32_t newParentWindowId)13804 WMError SceneSessionManager::SetParentWindow(int32_t subWindowId, int32_t newParentWindowId)
13805 {
13806     return taskScheduler_->PostSyncTask([this, subWindowId, newParentWindowId, where = __func__] {
13807         auto subSession = GetSceneSession(subWindowId);
13808         if (!subSession || !WindowHelper::IsSubWindow(subSession->GetWindowType())) {
13809             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s subSession is nullptr or type invalid", where);
13810             return WMError::WM_ERROR_INVALID_WINDOW;
13811         }
13812         int32_t oldParentWindowId = subSession->GetParentPersistentId();
13813         auto oldParentSession = GetSceneSession(oldParentWindowId);
13814         if (oldParentSession == nullptr) {
13815             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession is nullptr", where);
13816             return WMError::WM_ERROR_INVALID_PARENT;
13817         }
13818         auto oldWindowType = oldParentSession->GetWindowType();
13819         if (!WindowHelper::IsMainWindow(oldWindowType) && !WindowHelper::IsFloatOrSubWindow(oldWindowType)) {
13820             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession window type invalid", where);
13821             return WMError::WM_ERROR_INVALID_PARENT;
13822         }
13823         auto newParentSession = GetSceneSession(newParentWindowId);
13824         if (newParentSession == nullptr) {
13825             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is nullptr", where);
13826             return WMError::WM_ERROR_INVALID_PARENT;
13827         }
13828         TLOGND(WmsLogTag::WMS_SUB, "%{public}s subWindowId: %{public}d oldParentWindowId: %{public}d "
13829             "newParentWindowId: %{public}d", where, subWindowId, oldParentWindowId, newParentWindowId);
13830         auto newWindowType = newParentSession->GetWindowType();
13831         if (!WindowHelper::IsMainWindow(newWindowType) && !WindowHelper::IsFloatOrSubWindow(newWindowType)) {
13832             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession window type invalid", where);
13833             return WMError::WM_ERROR_INVALID_PARENT;
13834         }
13835         if (oldParentSession->GetCallingPid() != newParentSession->GetCallingPid()) {
13836             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s callingPid not same", where);
13837             return WMError::WM_ERROR_INVALID_PARENT;
13838         }
13839         if (newParentSession->IsAncestorsSession(subWindowId)) {
13840             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is subsession ancestor", where);
13841             return WMError::WM_ERROR_INVALID_PARENT;
13842         }
13843         return SetParentWindowInner(subSession, oldParentSession, newParentSession);
13844     });
13845 }
13846 
MinimizeByWindowId(const std::vector<int32_t> & windowIds)13847 WMError SceneSessionManager::MinimizeByWindowId(const std::vector<int32_t>& windowIds)
13848 {
13849     if (!SessionPermission::IsSystemServiceCalling()) {
13850         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system service.");
13851         return WMError::WM_ERROR_INVALID_PERMISSION;
13852     }
13853     if (windowIds.empty()) {
13854         TLOGE(WmsLogTag::WMS_LIFE, "The vector of windowids is empty.");
13855         return WMError::WM_ERROR_INVALID_PARAM;
13856     }
13857     taskScheduler_->PostAsyncTask([this, windowIds, where = __func__]() {
13858         for (const auto& persistentId : windowIds) {
13859             auto sceneSession = GetSceneSession(persistentId);
13860             if (sceneSession == nullptr) {
13861                 TLOGE(WmsLogTag::WMS_LIFE, "could not find the window, persistentId:%{public}d", persistentId);
13862                 continue;
13863             } else {
13864                 sceneSession->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
13865                 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d", where, persistentId);
13866             }
13867         }
13868     }, __func__);
13869     return WMError::WM_OK;
13870 }
13871 } // namespace OHOS::Rosen
13872